diff --git a/.env b/.env new file mode 100644 index 0000000..6f809cc --- /dev/null +++ b/.env @@ -0,0 +1 @@ +SKIP_PREFLIGHT_CHECK=true diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..da518c8 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,31 @@ +module.exports = { + extends: ['airbnb-typescript', 'eslint-config-prettier'], + parserOptions: { + project: './tsconfig.eslint.json', + }, + plugins: ['prettier'], + rules: { + 'prettier/prettier': [ + 'error', + { + singleQuote: true, + printWidth: 80, + arrowParens: 'avoid', + trailingComma: 'all', + }, + ], + // incompatible with prettier + 'react/jsx-curly-newline': 'off', + 'react/jsx-indent': 'off', + 'react/jsx-wrap-multilines': 'off', + 'react/jsx-closing-tag-location': 'off', + 'react/no-array-index-key': 'warn', + '@typescript-eslint/indent': 'off', + + // we're using typescript, so we have prop types + 'react/prop-types': 'off', + + // personal preference + 'react/jsx-props-no-spreading': 'off', + }, +}; diff --git a/package.json b/package.json index d867458..19013b4 100644 --- a/package.json +++ b/package.json @@ -7,8 +7,11 @@ "dependencies": { "@material-ui/core": "4.11.0", "@material-ui/icons": "4.9.1", + "@material-ui/styles": "4.11.3", "autoprefixer": "10.0.2", "chart.js": "2.9.3", + "chartjs-plugin-dragdata": "1.1.3", + "csstype": "3.0.6", "filter": "0.1.1", "gaussian-convolution-kernel": "1.0.0", "ml-dataset-iris": "1.1.1", @@ -22,13 +25,16 @@ "react": "16.13.1", "react-chartjs-2": "2.10.0", "react-dom": "16.13.1", + "react-router": "5.2.0", "react-router-dom": "5.2.0", "serialize-javascript": "4.0.0", + "tailwind": "4.0.0", + "tailwindcss": "1.9.6", + "tailwindcss-blend-mode": "1.0.0", "typeface-open-sans": "0.0.75", "typeface-roboto": "0.0.75", "typeface-roboto-mono": "0.0.75", - "typefaces": "0.0.1", - "chartjs-plugin-dragdata": "1.1.3" + "typefaces": "0.0.1" }, "devDependencies": { "@testing-library/dom": "5.6.1", @@ -41,12 +47,20 @@ "@types/react": "16.9.49", "@types/react-dom": "16.9.8", "@types/react-router-dom": "5.1.7", + "@typescript-eslint/eslint-plugin": "4.14.1", + "@typescript-eslint/parser": "4.14.1", + "eslint": "7.19.0", + "eslint-config-airbnb-typescript": "12.0.0", + "eslint-config-prettier": "7.2.0", + "eslint-plugin-import": "2.22.1", + "eslint-plugin-jsx-a11y": "6.4.1", + "eslint-plugin-prettier": "3.3.1", + "eslint-plugin-react": "7.22.0", + "eslint-plugin-react-hooks": "4.2.0", "postcss": "8.1.13", "postcss-cli": "7.1.2", + "prettier": "2.2.1", "react-scripts": "4.0.1", - "tailwind": "4.0.0", - "tailwindcss": "1.9.6", - "tailwindcss-blend-mode": "1.0.0", "typescript": "4.0.2" }, "scripts": { @@ -54,12 +68,10 @@ "build": "npm run build:css && react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject", + "lint": "eslint . --fix", "build:css": "postcss src/assets/tailwind.css -o src/assets/main.css", "watch:css": "postcss src/assets/tailwind.css -o src/assets/main.css" }, - "eslintConfig": { - "extends": "react-app" - }, "browserslist": { "production": [ ">0.2%", diff --git a/postcss.config.js b/postcss.config.js index c26935a..dec80b3 100644 --- a/postcss.config.js +++ b/postcss.config.js @@ -1,6 +1,5 @@ const tailwindcss = require('tailwindcss'); + module.exports = { - plugins: [ - tailwindcss('./tailwind.config.js') - ] + plugins: [tailwindcss('./tailwind.config.js')], }; diff --git a/src/App.js b/src/App.js deleted file mode 100644 index 177f8c4..0000000 --- a/src/App.js +++ /dev/null @@ -1,50 +0,0 @@ -import React from 'react'; -import { BrowserRouter, Route, Switch } from 'react-router-dom'; -import { createMuiTheme } from '@material-ui/core/styles'; -import { ThemeProvider } from '@material-ui/styles'; -import Navbar from "./Navbar"; -import Footer from './footer'; - -import './index.css'; -import AboutPage from "./aboutPage/AboutPage" -import LandingPage from "./landingPage/LandingPage"; -import ModulePage from "./modulePage/ModulePage"; - -function App() { - return ( - -
- -
- -
-
- - - - - - -
-
-
-
-
-
- ); -} - -// change colors as needed idk -const THEME = createMuiTheme({ - palette: { - primary: { - main: '#394D73' // same as footer color - }, - secondary: { - main: '#0FD4C0' // logo teal - }, - }, -}); - -export default App; \ No newline at end of file diff --git a/src/App.jsx b/src/App.jsx new file mode 100644 index 0000000..4d88882 --- /dev/null +++ b/src/App.jsx @@ -0,0 +1,50 @@ +import React from 'react'; +import { BrowserRouter, Route, Switch } from 'react-router-dom'; +import { createMuiTheme } from '@material-ui/core/styles'; +import { ThemeProvider } from '@material-ui/styles'; +import Navbar from './Navbar'; +import Footer from './footer'; + +import './index.css'; +import AboutPage from './aboutPage/AboutPage'; +import LandingPage from './landingPage/LandingPage'; +import ModulePage from './modulePage/ModulePage'; + +// change colors as needed +const THEME = createMuiTheme({ + palette: { + primary: { + main: '#394D73', // same as footer color + }, + secondary: { + main: '#0FD4C0', // logo teal + }, + }, +}); + +function App() { + return ( + +
+ +
+ +
+
+ + + + + + +
+
+
+
+
+
+ ); +} + +export default App; diff --git a/src/ModuleDropdown.js b/src/ModuleDropdown.js deleted file mode 100644 index ad659f5..0000000 --- a/src/ModuleDropdown.js +++ /dev/null @@ -1,34 +0,0 @@ -import React from 'react'; -import descriptions from './media/modules/module_descriptions.json'; - -export default class ModuleDropdown extends React.Component { - state = { - buttonHover: false, - dropdownHover: false - } - - render() { - return ( -
- -
this.setState((prevState) => ({buttonHover: prevState.buttonHover, dropdownHover: true}))} - onMouseOut={() => this.setState((prevState) => ({buttonHover: prevState.buttonHover, dropdownHover: false}))}> -
- { - descriptions.modules.map((module) => -
- - {module.dropdownTitle} - -
- ) - } -
-
- ); - } -} \ No newline at end of file diff --git a/src/ModuleDropdown.jsx b/src/ModuleDropdown.jsx new file mode 100644 index 0000000..1c3716b --- /dev/null +++ b/src/ModuleDropdown.jsx @@ -0,0 +1,45 @@ +import React, { useState } from 'react'; +import descriptions from './media/modules/module_descriptions.json'; + +export default function ModuleDropdown() { + const [buttonHover, setButtonHover] = useState(false); + const [dropdownHover, setDropdownHover] = useState(false); + + return ( +
+ +
setDropdownHover(true)} + onFocus={() => setDropdownHover(true)} + onMouseOut={() => setDropdownHover(false)} + onBlur={() => setDropdownHover(false)} + > +
+ {descriptions.modules.map(module => ( +
+ + {module.dropdownTitle} + +
+ ))} +
+
+ ); +} diff --git a/src/Navbar.js b/src/Navbar.js deleted file mode 100644 index 87a27df..0000000 --- a/src/Navbar.js +++ /dev/null @@ -1,29 +0,0 @@ -import React from 'react'; -import ModuleDropdown from "./ModuleDropdown"; -import logo from './media/landingPage/logo_blink.svg'; - -export default function Navbar() { - return ( - - ); -} diff --git a/src/Navbar.jsx b/src/Navbar.jsx new file mode 100644 index 0000000..94cad2f --- /dev/null +++ b/src/Navbar.jsx @@ -0,0 +1,43 @@ +import React from 'react'; +import ModuleDropdown from './ModuleDropdown'; +import logo from './media/landingPage/logo_blink.svg'; + +export default function Navbar() { + return ( + + ); +} diff --git a/src/aboutPage/AboutPage.tsx b/src/aboutPage/AboutPage.tsx index c162293..81bd25f 100644 --- a/src/aboutPage/AboutPage.tsx +++ b/src/aboutPage/AboutPage.tsx @@ -7,39 +7,62 @@ import danPic from '../media/aboutPage/danPic.jpg'; import irisPic from '../media/aboutPage/irisPic.jpg'; import maxPic from '../media/aboutPage/maxPic.png'; -const AboutPage = () => { - return ( -
-
-

- ABOUT US -

-

- Team Description -

-
-
- - - - - - -
-
- ); -} +const AboutPage = () => ( +
+
+

+ ABOUT US +

+

Team Description

+
+
+ + + + + + +
+
+); -export default AboutPage; \ No newline at end of file +export default AboutPage; diff --git a/src/aboutPage/ProfileCard.tsx b/src/aboutPage/ProfileCard.tsx index 5f91181..3d349b2 100644 --- a/src/aboutPage/ProfileCard.tsx +++ b/src/aboutPage/ProfileCard.tsx @@ -3,53 +3,79 @@ import linkedinIcon from '../media/aboutPage/iconmonstr-linkedin-1.svg'; import emailIcon from '../media/aboutPage/mail-24px.svg'; /** - * - * @param props + * + * @param props * @param props.image filepath to the image * @param props.name name of the person * @param props.title position title of the person * @param props.email email address of the person * @param props.linkedin linkedin url of the person */ -const ProfileCard = (props: - { image: string, name: string, title: string, email: string, linkedin: string }) => { - const [hovered, setHovered] = useState(false); +type ProfileCardType = { + image: string; + name: string; + title: string; + email: string; + linkedin: string; +}; +const ProfileCard: React.FC = ({ + image, + name, + title, + email, + linkedin, +}) => { + const [hovered, setHovered] = useState(false); - //TODO all these images need to be hosted somewhere? - const Overlay = () => ( -
- -
- LinkedIn Address -
-
- -
- Email Address -
-
+ // TODO all these images need to be hosted somewhere? + const Overlay = () => ( +
+ +
+ LinkedIn Address
- ) - return ( -
+ ); + return ( +
+
setHovered(true)} + onMouseLeave={() => setHovered(false)} + > + {hovered && } + Profile +
+
+

+ {name} +

+

+ {title} +

+
+
+ ); +}; -export default ProfileCard; \ No newline at end of file +export default ProfileCard; diff --git a/src/footer.js b/src/footer.js deleted file mode 100644 index 0013d0e..0000000 --- a/src/footer.js +++ /dev/null @@ -1,41 +0,0 @@ -import React from "react"; -import logo from './media/landingPage/staticLogo.svg'; - -function Footer() { - - const scrollTop = () => { - window.scrollTo({top: 0, behavior: 'smooth'}); - }; - - return ( - - - - ); -} - -export default Footer; \ No newline at end of file diff --git a/src/footer.jsx b/src/footer.jsx new file mode 100644 index 0000000..220c15a --- /dev/null +++ b/src/footer.jsx @@ -0,0 +1,67 @@ +import React from 'react'; +import logo from './media/landingPage/staticLogo.svg'; + +function Footer() { + const scrollTop = () => { + // eslint-disable-next-line + window.scrollTo({ top: 0, behavior: 'smooth' }); + }; + + return ( + + ); +} + +export default Footer; diff --git a/src/index.js b/src/index.jsx similarity index 79% rename from src/index.js rename to src/index.jsx index 7c8385e..3dcba36 100644 --- a/src/index.js +++ b/src/index.jsx @@ -3,15 +3,15 @@ import ReactDOM from 'react-dom'; import './assets/main.css'; import App from './App'; import * as serviceWorker from './serviceWorker'; -import "typeface-roboto"; -import "typeface-open-sans"; - +import 'typeface-roboto'; +import 'typeface-open-sans'; ReactDOM.render( , - document.getElementById('root') + // eslint-disable-next-line + document.getElementById('root'), ); // If you want your app to work offline and load faster, you can change diff --git a/src/landingPage/LandingPage.tsx b/src/landingPage/LandingPage.tsx index 4894dd7..907a07d 100644 --- a/src/landingPage/LandingPage.tsx +++ b/src/landingPage/LandingPage.tsx @@ -1,42 +1,61 @@ import React from 'react'; +import CSS from 'csstype'; import background_img from '../media/landingPage/background.jpeg'; import landing_background from '../media/landingPage/background_landing_page.svg'; import descriptions from '../media/modules/module_descriptions.json'; -import ModuleIntro from "./ModuleIntro"; -import CSS from 'csstype'; +import ModuleIntro from './ModuleIntro'; -let top_style: CSS.Properties = {backgroundImage: `url(${background_img})`}; -let bot_style: CSS.Properties = {backgroundImage: `url(${landing_background})`}; +const topStyle: CSS.Properties = { backgroundImage: `url(${background_img})` }; +const botStyle: CSS.Properties = { + backgroundImage: `url(${landing_background})`, +}; /** * Renders the landing page. */ export default function LandingPage() { return ( -
-
-
-

Your Eye and AI

-

Professor Mingolla

-
-
-

Developed by Sandbox

-
+
+
+
+

+ Your Eye and AI +

+

+ Professor Mingolla +

-
-
    - { - descriptions.modules.map((module) => - -
  • - -
  • -
    - ) - } -
+
+

+ Developed by Sandbox +

+
+
    + {descriptions.modules.map(module => ( + +
  • + +
  • +
    + ))} +
+
+
); -}; \ No newline at end of file +} diff --git a/src/landingPage/ModuleIntro.tsx b/src/landingPage/ModuleIntro.tsx index 232b377..4cb9cd7 100644 --- a/src/landingPage/ModuleIntro.tsx +++ b/src/landingPage/ModuleIntro.tsx @@ -1,8 +1,22 @@ import React from 'react'; -import mod8 from '../media/modules/mod8.png' -import mod9 from '../media/modules/mod9.png' -import mod10 from '../media/modules/mod10.png' -import mod11 from '../media/modules/mod11.png' +import mod8 from '../media/modules/mod8.png'; +import mod9 from '../media/modules/mod9.png'; +import mod10 from '../media/modules/mod10.png'; +import mod11 from '../media/modules/mod11.png'; + +function GetCoverImage(imgName: string) { + switch (imgName) { + case 'mod8': + return mod8; + case 'mod9': + return mod9; + case 'mod10': + return mod10; + case 'mod11': + return mod11; + default: + } +} /** * Renders one of the module previews on the landing page. @@ -14,30 +28,37 @@ import mod11 from '../media/modules/mod11.png' * @param props.margin x-margin of module (as a tailwind class), either left or right margin * @param props.imgSrc name of image on module */ -export default function ModuleIntro(props: - {title: string, body: string, bgColor: string, textColor: string, margin: string, imgSrc: string}) { - return ( -
-

{props.title}

-
- img -

{props.body}

-
-
- ); +type ModuleIntroType = { + title: string; + body: string; + bgColor: string; + textColor: string; + margin: string; + imgSrc: string; }; +const ModuleIntro: React.FC = ({ + title, + body, + bgColor, + textColor, + margin, + imgSrc, +}) => ( +
+

+ {title} +

+
+ img +

{body}

+
+
+); -function GetCoverImage(imgName: string) { - switch(imgName) { - case 'mod8': - return mod8; - case 'mod9': - return mod9; - case 'mod10': - return mod10; - case 'mod11': - return mod11; - default: - return; - } -} +export default ModuleIntro; diff --git a/src/modulePage/ModulePage.tsx b/src/modulePage/ModulePage.tsx index 6f1cbd4..21821fb 100644 --- a/src/modulePage/ModulePage.tsx +++ b/src/modulePage/ModulePage.tsx @@ -1,57 +1,77 @@ -import React from "react"; -import {RouteComponentProps} from 'react-router'; -import ModuleSection from "./ModuleSection"; +import React from 'react'; +import { RouteComponentProps } from 'react-router'; +import ModuleSection from './ModuleSection'; import module8 from '../media/modules/module_8.json'; import module9 from '../media/modules/module_9.json'; import module10 from '../media/modules/module_10.json'; import module11 from '../media/modules/module_11.json'; -export interface ModuleSubsection { - "title": string, - "body": string, - "imgSrc": string +export interface ModuleSubsectionType { + title: string; + body: string; + imgSrc: string; } -interface ModuleSection { - "title": string, - "colorScheme": string, - "subsections": ModuleSubsection[], - "demoComp": string + +interface ModuleSectionType { + title: string; + colorScheme: string; + subsections: ModuleSubsectionType[]; + demoComp: string; } + interface Module { - "number": number, - "title": string, - "sections": ModuleSection[] + number: number; + title: string; + sections: ModuleSectionType[]; } -const modules: Record = {'computer-vision': module8, 'classification' : module9, 'perceptrons' : module10, 'neural-nets' : module11} + +const modules: Record = { + 'computer-vision': module8, + classification: module9, + perceptrons: module10, + 'neural-nets': module11, +}; /** * Renders the entire module page. * @param props.match.params.module name of the current module (route has path /modules/module) */ -export default function ModulePage(props: RouteComponentProps<{module: string}>) { - const module = modules[props.match.params.module]; - if (!module) { - return ( -
-

This module does not exist.

- Return to home -
- ) - } + +export default function ModulePage( + props: RouteComponentProps<{ module: string }>, +) { + const { + match: { + params: { module }, + }, + } = props; + const curModule = modules[module]; + + if (!curModule) { return ( -
-

{module.title}

-
    - { - module.sections.map((section) => - - ) - } -
-
+
+

This module does not exist.

+ Return to home +
); -} \ No newline at end of file + } + + return ( +
+

+ {curModule.title} +

+
    + {curModule.sections.map(section => ( + + ))} +
+
+ ); +} diff --git a/src/modulePage/ModuleSection.tsx b/src/modulePage/ModuleSection.tsx index 20dcbd3..306ff23 100644 --- a/src/modulePage/ModuleSection.tsx +++ b/src/modulePage/ModuleSection.tsx @@ -1,26 +1,143 @@ -import React from "react"; -import GaussianBlurDemo from "../modules/computerVision/gaussianBlur/GaussianBlurDemo"; -import GaborDemo from "../modules/computerVision/gaborFilter/gaborFilter"; -import DiffOfGaussianDemo from "../modules/computerVision/diffofgaussian/DiffOfGaussian"; -import HaarWaveletDemo from "../modules/computerVision/haarWavelet/HaarWaveletDemo"; -import { ImageSelectableDemo } from "../modules/computerVision/imageSelector/ImageSelectableDemo"; -import PCADemo from "../modules/stateSpaces/pca/PCA"; -import {RawDataTable, SelectableAxisChart, StaticAxisChart, AxisSelector, config as pcaConfig} from "../modules/stateSpaces/pca/PCA"; -import KMeans, {KMeansStepExample, InteractiveClusteringExample} from '../modules/stateSpaces/kmeans'; +import React from 'react'; +import GaussianBlurDemo from '../modules/computerVision/gaussianBlur/GaussianBlurDemo'; +import GaborDemo from '../modules/computerVision/gaborFilter/gaborFilter'; +import DiffOfGaussianDemo from '../modules/computerVision/diffofgaussian/DiffOfGaussian'; +import HaarWaveletDemo from '../modules/computerVision/haarWavelet/HaarWaveletDemo'; +import { ImageSelectableDemo } from '../modules/computerVision/imageSelector/ImageSelectableDemo'; +import PCADemo, { + RawDataTable, + SelectableAxisChart, + StaticAxisChart, + config as pcaConfig, +} from '../modules/stateSpaces/pca/PCA'; + +import KMeans, { + KMeansStepExample, + InteractiveClusteringExample, +} from '../modules/stateSpaces/kmeans'; import blank from '../media/modules/blank.png'; import animation1 from '../media/modules/computerVision/animation-1.gif'; import animation2 from '../media/modules/computerVision/animation-2.gif'; import animation3 from '../media/modules/computerVision/animation-3.gif'; -import {ModuleSubsection} from "./ModulePage"; -const lorem = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'; +const lorem = + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'; interface ColorScheme { - "bgColor": string, - "titleColor": string, - "headingColor": string, - "bodyColor": string, - "labelColorHex": string + bgColor: string; + titleColor: string; + headingColor: string; + bodyColor: string; + labelColorHex: string; +} + +interface ModuleSubsection { + title: string; + body: string; + imgSrc: string; +} + +function GetImage(imgName: string) { + switch (imgName) { + case 'blank': + return blank; + case 'animation1': + return animation1; + case 'animation2': + return animation2; + case 'animation3': + return animation3; + default: + } +} + +function getDemo(comp: string, scheme: ColorScheme) { + const demoArgs = { labelColor: scheme.titleColor }; + + switch (comp) { + case 'GaussianBlurDemo': + return ( + + ); + case 'GaborDemo': + return ( + + ); + case 'DiffOfGaussian': + return ( + + ); + case 'HaarWaveletDemo': + return ( + + ); + case 'PCADemo': + return ; + case 'RawDataTable': + return ; + case 'StaticAxisChart': + return ( + + ); + case 'SelectableAxisChart': + return ( + + ); + case 'PCASelectableAxisChart': + return ( + + ); + case 'InteractiveKMeans': + return ( +
+
+ ); + case 'StepKMeans': + return ( +
+
+ ); + case 'KMeans': + return ; + default: + return
; + } } /** @@ -29,97 +146,88 @@ interface ColorScheme { * @param props.title section title * @param props.sections subsections of the section * @param props.colorScheme configuration for the section's color scheme, see ColorScheme interface - * @param props.key section's identifier; usually the section title * @param props.demoComp name of the React component used as a demo */ -export default function ModuleSection(props: - {title: string, sections: ModuleSubsection[], colorScheme: string, key: string, demoComp: string}) { - const scheme = props.colorScheme === 'dark' ? { - "bgColor": "bg-moduleDarkBlue", - "titleColor": "text-modulePaleBlue", - "headingColor": "text-moduleTeal", - "bodyColor": "text-moduleOffwhite", - "labelColorHex": "#CBD9F2" - } : { - "bgColor": "bg-modulePaleBlue", - "titleColor": "text-moduleNavy", - "headingColor": "text-moduleDarkBlue", - "bodyColor": "text-moduleNavy", - "labelColorHex": "#394D73" - }; +type ModuleSectionType = { + title: string; + sections: ModuleSubsection[]; + colorScheme: string; + key: string; + demoComp: string; +}; +const ModuleSection: React.FC = ({ + title, + sections, + colorScheme, + demoComp, +}) => { + const scheme = + colorScheme === 'dark' + ? { + bgColor: 'bg-moduleDarkBlue', + titleColor: 'text-modulePaleBlue', + headingColor: 'text-moduleTeal', + bodyColor: 'text-moduleOffwhite', + labelColorHex: '#CBD9F2', + } + : { + bgColor: 'bg-modulePaleBlue', + titleColor: 'text-moduleNavy', + headingColor: 'text-moduleDarkBlue', + bodyColor: 'text-moduleNavy', + labelColorHex: '#394D73', + }; - return ( -
-
-

{props.title}

-
    - { - props.sections.map((section, index) => { - return ( -
    - -
    -

    {section.body || lorem}

    -
    - -
    - ); - }) - } -
- { - getDemo(props.demoComp, scheme) - } + return ( +
+
+

+ {title} +

+
    + {/* eslint-disable-next-line */} + {sections.map((section, index) => ( +
    + +
    +

    + {section.body || lorem} +

    +
    +
    -
- ); -} - -function GetImage(imgName: string) { - switch(imgName) { - case 'blank': - return blank; - case 'animation1': - return animation1; - case 'animation2': - return animation2; - case 'animation3': - return animation3; - default: - return; - } -} + ))} + + {getDemo(demoComp, scheme)} +
+
+ ); +}; -function getDemo(comp: string, scheme: ColorScheme) { - const demoArgs = {labelColor: scheme.titleColor} - - switch (comp) { - case "GaussianBlurDemo": - return - case "GaborDemo": - return - case "DiffOfGaussian": - return - case "HaarWaveletDemo": - return - case "PCADemo": - return - case "RawDataTable": - return - case "StaticAxisChart": - return - case "SelectableAxisChart": - return - case "PCASelectableAxisChart": - return - case "InteractiveKMeans": - return
- case "StepKMeans": - return
- case "KMeans": - return - default: return
- } -} +export default ModuleSection; diff --git a/src/modules/computerVision/common/DiffofFiltered.tsx b/src/modules/computerVision/common/DiffofFiltered.tsx index 523379a..9318bae 100644 --- a/src/modules/computerVision/common/DiffofFiltered.tsx +++ b/src/modules/computerVision/common/DiffofFiltered.tsx @@ -1,52 +1,56 @@ import React from 'react'; import InteractiveFilter from './InteractiveFilter'; -import { convolute } from './filter'; -import { getPixels, createImageData } from './filter'; - -const pixelmatch = require('pixelmatch'); +import { convolute, getPixels } from './filter'; // http://dev.theomader.com/gaussian-kernel-calculator/ // https://blog.cloudboost.io/using-html5-canvas-with-react-ff7d93f5dc76 -const FilterByDiffKernel = (props: { kernel?: number[], kernel2?:number[], imgUrl: string }) => { - - return ( - { - - - props.kernel && convolute(inCanvas, outCanvas, false, props.kernel) - let check = getPixels(outCanvas) - if (!check) { - return ; - } - let result1 = Uint8ClampedArray.from(check.data) - - - props.kernel2 && convolute(inCanvas, outCanvas, false, props.kernel2) - let check2 = getPixels(outCanvas) - - if (!check2) { - return ; - } - let result2 = Uint8ClampedArray.from(check2.data) - - let width = check.width - let height = check.height - - let diff = result1.map((pix, i)=> ((i+1)%4== 0 ? 255 : 255 - Math.abs(pix - result2[i]))); - - - let output = new ImageData(diff, width, height) - - outCanvas.getContext('2d')?.putImageData(output, 0, 0); - - - }} - /> - ) -} - -export default FilterByDiffKernel; \ No newline at end of file +type DiffByKernelType = { + kernel?: number[]; + kernel2?: number[]; + imgUrl: string; +}; + +const FilterByDiffKernel: React.FC = ({ + kernel, + kernel2, + imgUrl, +}) => ( + { + if (kernel) { + convolute(inCanvas, outCanvas, false, kernel); + } + const check = getPixels(outCanvas); + if (!check) { + return; + } + const result1 = Uint8ClampedArray.from(check.data); + + if (kernel2) { + convolute(inCanvas, outCanvas, false, kernel2); + } + const check2 = getPixels(outCanvas); + + if (!check2) { + return; + } + const result2 = Uint8ClampedArray.from(check2.data); + + const { width } = check; + const { height } = check; + + const diff = result1.map((pix, i) => + (i + 1) % 4 === 0 ? 255 : 255 - Math.abs(pix - result2[i]), + ); + + const output = new ImageData(diff, width, height); + + outCanvas.getContext('2d')?.putImageData(output, 0, 0); + }} + /> +); + +export default FilterByDiffKernel; diff --git a/src/modules/computerVision/common/FilterByKernel.tsx b/src/modules/computerVision/common/FilterByKernel.tsx index f2b357f..ce3d176 100644 --- a/src/modules/computerVision/common/FilterByKernel.tsx +++ b/src/modules/computerVision/common/FilterByKernel.tsx @@ -5,17 +5,21 @@ import { convolute } from './filter'; // http://dev.theomader.com/gaussian-kernel-calculator/ // https://blog.cloudboost.io/using-html5-canvas-with-react-ff7d93f5dc76 -const FilterByKernel = (props: { kernel?: number[], imgUrl: string }) => { +type FilterByKernelType = { + kernel?: number[]; + imgUrl: string; +}; - return ( - { - props.kernel && convolute(inCanvas, outCanvas, true, props.kernel) - }} - /> - ) -} +const FilterByKernel: React.FC = ({ kernel, imgUrl }) => ( + { + if (kernel) { + convolute(inCanvas, outCanvas, true, kernel); + } + }} + /> +); -export default FilterByKernel; \ No newline at end of file +export default FilterByKernel; diff --git a/src/modules/computerVision/common/InteractiveFilter.tsx b/src/modules/computerVision/common/InteractiveFilter.tsx index 0a4677d..7ea0710 100644 --- a/src/modules/computerVision/common/InteractiveFilter.tsx +++ b/src/modules/computerVision/common/InteractiveFilter.tsx @@ -4,73 +4,89 @@ import React, { useLayoutEffect, useRef, useState } from 'react'; // https://blog.cloudboost.io/using-html5-canvas-with-react-ff7d93f5dc76 /** - * - * @param props - * @param props.filter function that writes a filtered image to `outCanvas`, + * + * @param props + * @param props.filter function that writes a filtered image to `outCanvas`, * given the original image on `inCanvas` * @param props.imgUrl url to the image to display - * @param props.disabled whether or not the "apply filter" button should be disabled + * @param props.disabled whether or not the "apply filter" button should be disabled */ -const InteractiveFilter = (props: { - filter: (inCanvas: HTMLCanvasElement, outCanvas: HTMLCanvasElement) => any, - imgUrl: string, - disabled: boolean +type InteractiveFilterType = { + filter: (inCanvas: HTMLCanvasElement, outCanvas: HTMLCanvasElement) => any; + imgUrl: string; + disabled: boolean; +}; +const InteractiveFilter: React.FC = ({ + filter, + imgUrl, + disabled, }) => { + const [isFiltered, setIsFiltered] = useState(false); + const [imgWidth, setImgWidth] = useState(undefined); + const [imgHeight, setImgHeight] = useState(undefined); + const inputCanvas = useRef(null); + const outputCanvas = useRef(null); + const imgRef = useRef(null); - const [isFiltered, setIsFiltered] = useState(false); - const [imgWidth, setImgWidth] = useState(undefined); - const [imgHeight, setImgHeight] = useState(undefined); - const inputCanvas = useRef(null); - const outputCanvas = useRef(null); - const imgRef = useRef(null); + useLayoutEffect(() => { + const inputElem = inputCanvas.current; // get the DOM element for the canvas + const outputElem = outputCanvas.current; + const imgElem = imgRef.current; + if (!(inputElem && outputElem && imgElem)) return; - useLayoutEffect(() => { - const inputElem = inputCanvas.current; // get the DOM element for the canvas - const outputElem = outputCanvas.current; - const imgElem = imgRef.current; - if (!(inputElem && outputElem && imgElem)) return; + imgElem.onload = () => { + setImgHeight(imgElem.height); + setImgWidth(imgElem.width); + inputElem.getContext('2d')?.drawImage(imgElem, 0, 0); + outputElem.getContext('2d')?.drawImage(imgElem, 0, 0); + }; + }, []); - imgElem.onload = () => { - setImgHeight(imgElem.height); - setImgWidth(imgElem.width); - inputElem.getContext('2d')?.drawImage(imgElem, 0, 0); - outputElem.getContext('2d')?.drawImage(imgElem, 0, 0); - } - }, []) + const applyFilter = () => { + const inputElem = inputCanvas.current; // get the DOM element for the canvas + const outputElem = outputCanvas.current; + if (!(inputElem && outputElem)) return; + filter(inputElem, outputElem); + setIsFiltered(true); + }; - const applyFilter = () => { - const inputElem = inputCanvas.current; // get the DOM element for the canvas - const outputElem = outputCanvas.current; - if (!(inputElem && outputElem)) return; - props.filter(inputElem, outputElem); - setIsFiltered(true); - } + const resetImage = () => { + const outputElem = outputCanvas.current; + const imgElem = imgRef.current; + if (!(outputElem && imgElem)) return; + const ctxt = outputElem.getContext('2d'); + ctxt?.clearRect(0, 0, ctxt.canvas.width, ctxt.canvas.height); + ctxt?.drawImage(imgElem, 0, 0); + setIsFiltered(false); + }; - const resetImage = () => { - const outputElem = outputCanvas.current; - const imgElem = imgRef.current; - if (!(outputElem && imgElem)) return; - const ctxt = outputElem.getContext('2d'); - ctxt?.clearRect(0, 0, ctxt.canvas.width, ctxt.canvas.height); - ctxt?.drawImage(imgElem, 0, 0); - setIsFiltered(false); - } + return ( +
+
+ input + + +
+ +
+ ); +}; - return ( -
-
- input - - -
- -
- ) -} - -export default InteractiveFilter; \ No newline at end of file +export default InteractiveFilter; diff --git a/src/modules/computerVision/common/KernelDisplay.tsx b/src/modules/computerVision/common/KernelDisplay.tsx index f19cb08..939b805 100644 --- a/src/modules/computerVision/common/KernelDisplay.tsx +++ b/src/modules/computerVision/common/KernelDisplay.tsx @@ -2,66 +2,78 @@ import React, { useState } from 'react'; import FormControlLabel from '@material-ui/core/FormControlLabel'; import Switch from '@material-ui/core/Switch'; +function getCellColor(val: number, max: number, min: number) { + if (max === min) { + return 'rgb(0, 212, 192)'; + } + const red = 255 - ((val - min) / (max - min)) * 255; + return `rgb(${red}, 212, 192)`; +} -const KernelDisplay = (props: { kernelGrid?: number[][] , labelColor: string}) => { - const [showNums, setShowNums] = useState(true); +type KernelGridType = { + kernelGrid?: number[][]; + labelColor: string; +}; - if (!props.kernelGrid) return <>; +const KernelDisplay: React.FC = ({ + kernelGrid = undefined, + labelColor, +}) => { + const [showNums, setShowNums] = useState(true); - let max = 0; - let min = Infinity; - props.kernelGrid.forEach(row => row.forEach(ele => { - if (ele > max) max = ele; - if (ele < min) min = ele; - })) + if (!kernelGrid) return <>; - const getCell = (val: number, j: number) => { - const color = getCellColor(val, max, min); - return ( - - {val.toFixed(3)} - - ); - } + let max = 0; + let min = Infinity; + kernelGrid.forEach(row => + row.forEach(ele => { + if (ele > max) max = ele; + if (ele < min) min = ele; + }), + ); + const getCell = (val: number, j: number) => { + const color = getCellColor(val, max, min); return ( -
-
- - {props.kernelGrid.map((row, i) => ( - - {row.map((val, j) => getCell(val, j))} - - ))} -
-
- setShowNums(e.target.checked)} - color="primary" - /> - } className={props.labelColor} - label="Show kernel numbers" - /> -
+ + {val.toFixed(3)} + ); -} + }; -function getCellColor(val: number, max: number, min: number) { - if (max === min) { - return `rgb(0, 212, 192)` - } else { - const red = 255 - ((val - min) / (max - min) * 255); - return `rgb(${red}, 212, 192)`; - } -} + return ( +
+
+ + + {kernelGrid.map((row, i) => ( + // eslint-disable-next-line + {row.map((val, j) => getCell(val, j))} + ))} + +
+
+ setShowNums(e.target.checked)} + color="primary" + /> + } + className={labelColor} + label="Show kernel numbers" + /> +
+ ); +}; -export default KernelDisplay; \ No newline at end of file +export default KernelDisplay; diff --git a/src/modules/computerVision/common/filter.tsx b/src/modules/computerVision/common/filter.tsx index 11da7a8..f5bde7e 100644 --- a/src/modules/computerVision/common/filter.tsx +++ b/src/modules/computerVision/common/filter.tsx @@ -1,54 +1,63 @@ - -export { - convolute, getPixels, createImageData -}; - /// utility functions for filtering / manipulating a DOM canvas // reference: https://www.html5rocks.com/en/tutorials/canvas/imagefilters/ +function getPixels(canvas: HTMLCanvasElement) { + const ctx = canvas.getContext('2d'); + return ctx && ctx.getImageData(0, 0, canvas.width, canvas.height); +} + /** * Run an image convolution based on inCanvas, and draws the output to outCanvas. - * Don't ask me how any of this works!!!! I dont know!!!!!!! - * + * Don't ask me how any of this works!!!! I dont know!!!!!!! + * * @param inCanvas the canvas to be filtered, with an image already drawn on it * @param outCanvas the canvas to be outputted to * @param animate whether or not to animate the filter by each row of pixels * @param weights the kernel (matrix of numbers) * @param opaque (optional) is the image opaque? */ -function convolute(inCanvas: HTMLCanvasElement, outCanvas: HTMLCanvasElement, animate: boolean, weights: number[], opaque?: boolean) { +function convolute( + inCanvas: HTMLCanvasElement, + outCanvas: HTMLCanvasElement, + animate: boolean, + weights: number[], + opaque?: boolean, +) { const pixels = getPixels(inCanvas); const output = getPixels(outCanvas); if (!pixels || !output) return; - var side = Math.round(Math.sqrt(weights.length)); - var halfSide = Math.floor(side / 2); - var src = pixels.data; - var sw = pixels.width; - var sh = pixels.height; + const side = Math.round(Math.sqrt(weights.length)); + const halfSide = Math.floor(side / 2); + const src = pixels.data; + const sw = pixels.width; + const sh = pixels.height; // pad output by the convolution matrix - var w = sw; - var h = sh; - var dst = output.data; + const w = sw; + const h = sh; + const dst = output.data; // go through the destination image pixels - var alphaFac = opaque ? 1 : 0; + const alphaFac = opaque ? 1 : 0; - const processRow = (y : number) => { - for (var x = 0; x < w; x++) { - var sy = y; - var sx = x; - var dstOff = (y * w + x) * 4; - var nextDstOff = ((y + 1) * w + x) * 4; + const processRow = (y: number) => { + for (let x = 0; x < w; x += 1) { + const sy = y; + const sx = x; + const dstOff = (y * w + x) * 4; + const nextDstOff = ((y + 1) * w + x) * 4; // calculate the weighed sum of the source image pixels that // fall under the convolution matrix - var r = 0, g = 0, b = 0, a = 0; - for (var cy = 0; cy < side; cy++) { - for (var cx = 0; cx < side; cx++) { - var scy = sy + cy - halfSide; - var scx = sx + cx - halfSide; + let r = 0; + let g = 0; + let b = 0; + let a = 0; + for (let cy = 0; cy < side; cy += 1) { + for (let cx = 0; cx < side; cx += 1) { + const scy = sy + cy - halfSide; + const scx = sx + cx - halfSide; if (scy >= 0 && scy < sh && scx >= 0 && scx < sw) { - var srcOff = (scy * sw + scx) * 4; - var wt = weights[cy * side + cx]; + const srcOff = (scy * sw + scx) * 4; + const wt = weights[cy * side + cx]; r += src[srcOff] * wt; g += src[srcOff + 1] * wt; b += src[srcOff + 2] * wt; @@ -56,7 +65,7 @@ function convolute(inCanvas: HTMLCanvasElement, outCanvas: HTMLCanvasElement, an } } } - + dst[dstOff] = r; dst[dstOff + 1] = g; dst[dstOff + 2] = b; @@ -65,31 +74,27 @@ function convolute(inCanvas: HTMLCanvasElement, outCanvas: HTMLCanvasElement, an dst[nextDstOff + 1] = 0; dst[nextDstOff + 2] = 0; } - } + }; if (animate) { - var y = 0; + let y = 0; const interval = setInterval(() => { processRow(y); - outCanvas.getContext("2d")?.putImageData(output, 0, 0); - y++; + outCanvas.getContext('2d')?.putImageData(output, 0, 0); + y += 1; if (y >= h) clearInterval(interval); }, 10); } else { - for (var y = 0; y < h; y++) { + for (let y = 0; y < h; y += 1) { processRow(y); } - outCanvas.getContext("2d")?.putImageData(output, 0, 0); + outCanvas.getContext('2d')?.putImageData(output, 0, 0); } } -function getPixels(canvas: HTMLCanvasElement) { - var ctx = canvas.getContext('2d'); - return ctx && ctx.getImageData(0, 0, canvas.width, canvas.height); -} - function createImageData(canvas: HTMLCanvasElement) { - var ctx = canvas.getContext('2d'); + const ctx = canvas.getContext('2d'); return ctx && ctx.createImageData(canvas.width, canvas.height); } +export { convolute, getPixels, createImageData }; diff --git a/src/modules/computerVision/diffofgaussian/DiffOfGaussian.tsx b/src/modules/computerVision/diffofgaussian/DiffOfGaussian.tsx index a093470..70681e3 100644 --- a/src/modules/computerVision/diffofgaussian/DiffOfGaussian.tsx +++ b/src/modules/computerVision/diffofgaussian/DiffOfGaussian.tsx @@ -6,119 +6,172 @@ import DiffofFiltered from '../common/DiffofFiltered'; // have to use require for this bc it doesn't have a module declaration file or something const generateGaussianKernel = require('gaussian-convolution-kernel'); - -const DoG = (props: { labelColor: string, imgUrl: string }) => { - const [kernel, setKernel] = useState(undefined); - const [kernel2, setKernel2] = useState(undefined); - const [kernelGrid, setKernelGrid] = useState(undefined); - const [kernelGrid2, setKernelGrid2] = useState(undefined); - - - const configureKernel = (kernelSize: number, sigma: number, sigma2: number) => { - - const newKernel: number[] = generateGaussianKernel(kernelSize, sigma); - const newKernel2: number[] = generateGaussianKernel(kernelSize, sigma2); - const newKernelGrid = newKernel.reduce((rslt: number[][], val, idx) => { - if (idx % kernelSize === 0) rslt.push([]); - rslt[rslt.length - 1].push(val); - return rslt; - }, []); - const newKernelGrid2 = newKernel2.reduce((rslt: number[][], val, idx) => { - if (idx % kernelSize === 0) rslt.push([]); - rslt[rslt.length - 1].push(val); - return rslt; - }, []); - - - // take difference of the two filters - // dog = difference of gaussians - // let dog = newKernel.map((inner, i) => (inner - newKernel2[i])); - - // let dogGrid = newKernelGrid.map((inner, i) => inner.map((v, j) => (v - newKernelGrid2[i][j]))); - - setKernel(newKernel); - setKernel2(newKernel2); - setKernelGrid(newKernelGrid); - setKernelGrid2(newKernelGrid2); - } - - return ( -
- -
- - -
- -

Filter by the First Kernel

- -

Filter by the Second Kernel

- -

Take the Difference of the Filtered Images

- - -
- ) -} - -const KernelConfig = (props: { onConfig: (kernelSize: number, sigma: number, sigma2: number) => void, labelColor: string }) => { - const [kernelSize, setKernelSize] = useState(5); - const [sigma, setSigma] = useState(1); - const [sigma2, setSigma2] = useState(3); - - const changeSigma = (e: any) => setSigma(parseFloat(e.target.value)); - const changeSigma2 = (e: any) => setSigma2(parseFloat(e.target.value)); - const changeKernelSize = (e: any) => setKernelSize(parseInt(e.target.value)); - - const invalidSize = (kernelSize % 2 !== 1 || kernelSize < 3 || kernelSize > 7) - const invalidConfig = !sigma || invalidSize; - return ( -
-
- Sigma - changeSigma(e)} /> - changeSigma(e)} /> -
-
- Sigma 2 - changeSigma2(e)} /> - changeSigma2(e)} /> -
-
- Kernel Size - changeKernelSize(e)} /> - changeKernelSize(e)} /> -
- {invalidSize ? 'Enter an odd kernel size, between 3 and 7' : ''} -
-
- +// function getBg(val: number, kernel?: number[]) { +// if (!kernel) return; +// const max = kernel[Math.floor(kernel.length / 2)]; +// const min = kernel[0]; +// const red = 200 - ((val - min) / (max - min)) * 200; +// return { background: `rgb(${red}, 212, 192)` }; +// } + +type KernelConfigType = { + labelColor: string; + onConfig: (kernelSize: number, sigma: number, sigma2: number) => void; +}; + +const KernelConfig: React.FC = ({ labelColor, onConfig }) => { + const [kernelSize, setKernelSize] = useState(5); + const [sigma, setSigma] = useState(1); + const [sigma2, setSigma2] = useState(3); + + const changeSigma = (e: any) => setSigma(parseFloat(e.target.value)); + const changeSigma2 = (e: any) => setSigma2(parseFloat(e.target.value)); + const changeKernelSize = (e: any) => + setKernelSize(parseInt(e.target.value, 10)); + + const invalidSize = kernelSize % 2 !== 1 || kernelSize < 3 || kernelSize > 7; + const invalidConfig = !sigma || invalidSize; + return ( +
+
+ Sigma + changeSigma(e)} + /> + changeSigma(e)} + /> +
+
+ Sigma 2 + changeSigma2(e)} + /> + changeSigma2(e)} + /> +
+
+ Kernel Size + changeKernelSize(e)} + /> + changeKernelSize(e)} + /> +
+ {invalidSize ? 'Enter an odd kernel size, between 3 and 7' : ''}
- ); -} - -function getBg(val: number, kernel?: number[]) { - if (!kernel) return; - const max = kernel[Math.floor(kernel.length / 2)]; - const min = kernel[0]; - const red = 200 - ((val - min) / (max - min) * 200); - return { background: `rgb(${red}, 212, 192)` }; -} - - - -export default DoG; \ No newline at end of file +
+ +
+ ); +}; + +type DoGType = { + labelColor: string; + imgUrl: string; +}; +const DoG: React.FC = ({ labelColor, imgUrl }) => { + const [kernel, setKernel] = useState(undefined); + const [kernel2, setKernel2] = useState(undefined); + const [kernelGrid, setKernelGrid] = useState( + undefined, + ); + const [kernelGrid2, setKernelGrid2] = useState( + undefined, + ); + + const configureKernel = ( + kernelSize: number, + sigma: number, + sigma2: number, + ) => { + const newKernel: number[] = generateGaussianKernel(kernelSize, sigma); + const newKernel2: number[] = generateGaussianKernel(kernelSize, sigma2); + const newKernelGrid = newKernel.reduce((rslt: number[][], val, idx) => { + if (idx % kernelSize === 0) rslt.push([]); + rslt[rslt.length - 1].push(val); + return rslt; + }, []); + const newKernelGrid2 = newKernel2.reduce((rslt: number[][], val, idx) => { + if (idx % kernelSize === 0) rslt.push([]); + rslt[rslt.length - 1].push(val); + return rslt; + }, []); + + // take difference of the two filters + // dog = difference of gaussians + // let dog = newKernel.map((inner, i) => (inner - newKernel2[i])); + + // let dogGrid = newKernelGrid.map((inner, i) => inner.map((v, j) => (v - newKernelGrid2[i][j]))); + + setKernel(newKernel); + setKernel2(newKernel2); + setKernelGrid(newKernelGrid); + setKernelGrid2(newKernelGrid2); + }; + + return ( +
+ +
+ + +
+ +

Filter by the First Kernel

+ +

Filter by the Second Kernel

+ +

Take the Difference of the Filtered Images

+ +
+ ); +}; + +export default DoG; diff --git a/src/modules/computerVision/gaborFilter/AngleSelector.tsx b/src/modules/computerVision/gaborFilter/AngleSelector.tsx index c66aa5b..bab8eec 100644 --- a/src/modules/computerVision/gaborFilter/AngleSelector.tsx +++ b/src/modules/computerVision/gaborFilter/AngleSelector.tsx @@ -3,73 +3,89 @@ import './AngleSelector.css'; import mainCircle from './main-circle.svg'; /** - * + * * @param props - * @param props.diameter {String} any valid css string for the height/width of the circle + * @param props.diameter {String} any valid css string for the height/width of the circle * @param props.initAngle {number} initial angle for the selector, in radians * @param props.onAngleChange {function} callback for when the angle changes */ -const AngleSelector = ({ diameter, initAngle = 0, onAngleChange }: - { diameter: string, initAngle?: number, onAngleChange: (angle :number) => any }) => { - const [moving, setMoving] = useState(false); - const [angle, setAngle] = useState(initAngle); //in radians - const dragHandle = (e: React.MouseEvent) => { - if (!moving) return; +type AngleSelectorType = { + diameter: string; + initAngle?: number; + onAngleChange: (angle: number) => any; +}; - const circle = document.getElementById("main-circle"); - if (!circle) return; - const circleBounds = circle.getBoundingClientRect(); - const radius = (circleBounds.right - circleBounds.left) / 2; - const x = e.clientX - circleBounds.left - radius; - const y = -e.clientY + circleBounds.top + radius; - let newAngle = Math.atan(y / x); - if (x < 0) newAngle = newAngle + Math.PI; - newAngle = newAngle % (Math.PI * 2); - setAngle(newAngle); - onAngleChange(newAngle); - } +const AngleSelector: React.FC = ({ + diameter, + initAngle = 0, + onAngleChange, +}) => { + const [moving, setMoving] = useState(false); + const [angle, setAngle] = useState(initAngle); // in radians - // todo normalize angles to unit circle - return ( -
-
-
-
setMoving(true)} - onMouseUp={() => setMoving(false)} - onMouseMove={dragHandle} - > -
-
-
-
-
- + const dragHandle = (e: React.MouseEvent) => { + if (!moving) return; + + const circle = document.getElementById('main-circle'); + if (!circle) return; + const circleBounds = circle.getBoundingClientRect(); + const radius = (circleBounds.right - circleBounds.left) / 2; + const x = e.clientX - circleBounds.left - radius; + const y = -e.clientY + circleBounds.top + radius; + let newAngle = Math.atan(y / x); + if (x < 0) newAngle += Math.PI; + newAngle %= Math.PI * 2; + setAngle(newAngle); + onAngleChange(newAngle); + }; + + // todo normalize angles to unit circle + return ( +
+
+
+
setMoving(true)} + onMouseUp={() => setMoving(false)} + onMouseMove={dragHandle} + > +
+
+
- ); -} +
+ +
+ ); +}; -export default AngleSelector; \ No newline at end of file +export default AngleSelector; diff --git a/src/modules/computerVision/gaborFilter/gaborFilter.tsx b/src/modules/computerVision/gaborFilter/gaborFilter.tsx index 3642223..13e95cc 100644 --- a/src/modules/computerVision/gaborFilter/gaborFilter.tsx +++ b/src/modules/computerVision/gaborFilter/gaborFilter.tsx @@ -1,158 +1,234 @@ import React, { useState } from 'react'; -import FilterByKernel from '../common/FilterByKernel'; -import KernelDisplay from '../common/KernelDisplay'; import Accordion from '@material-ui/core/Accordion'; import AccordionSummary from '@material-ui/core/AccordionSummary'; import AccordionDetails from '@material-ui/core/AccordionDetails'; import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; +import KernelDisplay from '../common/KernelDisplay'; +import FilterByKernel from '../common/FilterByKernel'; import AngleSelector from './AngleSelector'; - // mimics np.meshgrid in python function makeMeshgrid(sz: number[]) { + const radius = [Math.floor(sz[0] / 2.0), Math.floor(sz[1] / 2.0)]; - var radius = [Math.floor(sz[0] / 2.0), Math.floor(sz[1] / 2.0)] + const resultX = []; + const resultY = []; - var result_x = []; - var result_y = []; - - for (let i = 0; i < (2 * Math.floor(sz[1] / 2)) + 1; i++) { - let x_row = [] - for (let j = -radius[0]; j < radius[0] + 1; j++) { - x_row.push(j) - } - result_x.push(x_row) + for (let i = 0; i < 2 * Math.floor(sz[1] / 2) + 1; i += 1) { + const xRow = []; + for (let j = -radius[0]; j < radius[0] + 1; j += 1) { + xRow.push(j); } + resultX.push(xRow); + } - for (let i = -Math.floor(sz[1] / 2); i < Math.floor(sz[1] / 2) + 1; i++) { - let y_row = [] - for (let j = 0; j < sz[0] + 1; j++) { - y_row.push(i) - } - result_y.push(y_row) + for (let i = -Math.floor(sz[1] / 2); i < Math.floor(sz[1] / 2) + 1; i += 1) { + const yRow = []; + for (let j = 0; j < sz[0] + 1; j += 1) { + yRow.push(i); } + resultY.push(yRow); + } - return [result_x, result_y] + return [resultX, resultY]; } -//http://vision.psych.umn.edu/users/kersten/kersten-lab/courses/Psy5036W2017/Lectures/17_PythonForVision/Demos/html/2b.Gabor.html -function gaborFilter(sz: number, +type KernelConfigType = { + onConfig: ( + kernelSize: number, omega: number, theta: number, - func = Math.cos, - K = Math.PI) { - - // EXAMPLE INPUTS - - // let sz = [4,4] - // let omega = 0.3 - // let theta = Math.PI/4 - // let func = Math.cos - // let K = Math.PI - const sz1 = [sz, sz] - let xy = makeMeshgrid(sz1) - let x = xy[0] - let y = xy[1] - - let x1 = x.map((inner, i) => inner.map((v, j) => (v * Math.cos(theta)) + (y[i][j] * Math.sin(theta)))); - let y1 = x.map((inner, i) => inner.map((v, j) => (-v * Math.sin(theta)) + (y[i][j] * Math.cos(theta)))); - - let p = Math.pow(omega, 2) / (4 * Math.PI * Math.pow(K, 2)) - let gaussian = x1.map((inner, i) => inner.map((v, j) => p * Math.exp(-Math.pow(omega, 2) / (8 * Math.pow(K, 2)) * (4 * Math.pow(v, 2) + Math.pow(y1[i][j], 2))))); - let sinusoid = x1.map((inner, i) => inner.map((v, j) => (func(omega * v) * Math.exp(Math.pow(K, 2) / 2)))); - let gabor = sinusoid.map((inner, i) => inner.map((v, j) => (v * gaussian[i][j]))); - return gabor; -} - - -const GaborDemo = (props: {labelColor: string, imgUrl: string}) => { - const [kernel, setKernel] = useState(undefined); - const [kernelGrid, setKernelGrid] = useState(undefined); - - const configureKernel = (kernelSize: number, - omega: number, - theta: number, - K: number) => { - - const func = Math.cos; - - const gabor = gaborFilter(kernelSize, omega, theta, func, K) - const newKernel = gabor.flat(); - const newKernelGrid = gabor; - setKernel(newKernel); - setKernelGrid(newKernelGrid); - } - - return ( -
-
- - -
- -
- ) + K: number, + ) => void; + labelColor: string; +}; +const KernelConfig: React.FC = ({ onConfig, labelColor }) => { + const [kernelSize, setKernelSize] = useState(5); + const [omega, setOmega] = useState(1); + const [theta, setTheta] = useState(0); + const [K, setK] = useState(3.14); + + const changeOmega = (e: any) => setOmega(parseFloat(e.target.value)); + const changeKernelSize = (e: any) => + setKernelSize(parseInt(e.target.value, 10)); + const changeTheta = (t: number) => setTheta(t); + const changeK = (e: any) => setK(parseFloat(e.target.value)); + + const invalidConfig = kernelSize < 1 || kernelSize > 7; + return ( +
+
+ Kernel Size + changeKernelSize(e)} + /> + changeKernelSize(e)} + /> +
+
+ Theta + +
+ + } + > + Extra Parameters + + +
+ Omega + changeOmega(e)} + /> + changeOmega(e)} + /> +
+
+ K + changeK(e)} + /> + changeK(e)} + /> +
+
+
+ +
+ ); +}; + +// http://vision.psych.umn.edu/users/kersten/kersten-lab/courses/Psy5036W2017/Lectures/17_PythonForVision/Demos/html/2b.Gabor.html +function gaborFilter( + sz: number, + omega: number, + theta: number, + func = Math.cos, + K = Math.PI, +) { + // EXAMPLE INPUTS + + // let sz = [4,4] + // let omega = 0.3 + // let theta = Math.PI/4 + // let func = Math.cos + // let K = Math.PI + const sz1 = [sz, sz]; + const xy = makeMeshgrid(sz1); + const x = xy[0]; + const y = xy[1]; + + const x1 = x.map((inner, i) => + inner.map((v, j) => v * Math.cos(theta) + y[i][j] * Math.sin(theta)), + ); + const y1 = x.map((inner, i) => + inner.map((v, j) => -v * Math.sin(theta) + y[i][j] * Math.cos(theta)), + ); + + const p = omega ** 2 / (4 * Math.PI * K ** 2); + const gaussian = x1.map((inner, i) => + inner.map( + (v, j) => + p * + Math.exp((-(omega ** 2) / (8 * K ** 2)) * (4 * v ** 2 + y1[i][j] ** 2)), + ), + ); + const sinusoid = x1.map(inner => + inner.map(v => func(omega * v) * Math.exp(K ** 2 / 2)), + ); + const gabor = sinusoid.map((inner, i) => + inner.map((v, j) => v * gaussian[i][j]), + ); + return gabor; } -const KernelConfig = (props: { onConfig: (kernelSize: number, omega: number, theta: number, K: number) => void, labelColor: string}) => { - const [kernelSize, setKernelSize] = useState(5); - const [omega, setOmega] = useState(1); - const [theta, setTheta] = useState(0); - const [K, setK] = useState(3.14); - - const changeOmega = (e: any) => setOmega(parseFloat(e.target.value)); - const changeKernelSize = (e: any) => setKernelSize(parseInt(e.target.value)); - const changeTheta = (t: number) => setTheta(t); - const changeK = (e: any) => setK(parseFloat(e.target.value)); - - const invalidConfig = (kernelSize < 1 || kernelSize > 7) - return ( -
-
- Kernel Size - changeKernelSize(e)} /> - changeKernelSize(e)} /> - -
-
- Theta - -
- - }> - Extra Parameters - - -
- Omega - changeOmega(e)} /> - changeOmega(e)} /> -
-
- K - changeK(e)} /> - changeK(e)} /> -
-
-
- -
- ); -} - -export default GaborDemo; \ No newline at end of file +type GaborDemoType = { + labelColor: string; + imgUrl: string; +}; +const GaborDemo: React.FC = ({ labelColor, imgUrl }) => { + const [kernel, setKernel] = useState(undefined); + const [kernelGrid, setKernelGrid] = useState( + undefined, + ); + + const configureKernel = ( + kernelSize: number, + omega: number, + theta: number, + K: number, + ) => { + const func = Math.cos; + + const gabor = gaborFilter(kernelSize, omega, theta, func, K); + const newKernel = gabor.flat(); + const newKernelGrid = gabor; + setKernel(newKernel); + setKernelGrid(newKernelGrid); + }; + + return ( +
+
+ + +
+ +
+ ); +}; + +export default GaborDemo; diff --git a/src/modules/computerVision/gaussianBlur/GaussianBlurDemo.tsx b/src/modules/computerVision/gaussianBlur/GaussianBlurDemo.tsx index 3fce400..e91f1bb 100644 --- a/src/modules/computerVision/gaussianBlur/GaussianBlurDemo.tsx +++ b/src/modules/computerVision/gaussianBlur/GaussianBlurDemo.tsx @@ -4,74 +4,116 @@ import KernelDisplay from '../common/KernelDisplay'; // have to use require for this bc it doesn't have a module declaration file or something const generateGaussianKernel = require('gaussian-convolution-kernel'); +type KernelConfigType = { + onConfig: (kernelSize: number, sigma: number) => void; + labelColor: string; +}; -const GaussianBlurDemo = (props: {labelColor: string, imgUrl: string}) => { - const [kernel, setKernel] = useState(undefined); - const [kernelGrid, setKernelGrid] = useState(undefined); +const KernelConfig: React.FC = ({ onConfig, labelColor }) => { + const [kernelSize, setKernelSize] = useState(5); + const [sigma, setSigma] = useState(1); - const configureKernel = (kernelSize: number, sigma: number) => { - let newKernel :number[]; - if (kernelSize === 1) { - newKernel = [1]; - } else { - newKernel = generateGaussianKernel(kernelSize, sigma); - } - const newKernelGrid = newKernel.reduce((rslt: number[][], val, idx) => { - if (idx % kernelSize === 0) rslt.push([]); - rslt[rslt.length - 1].push(val); - return rslt; - }, []); - setKernel(newKernel); - setKernelGrid(newKernelGrid); - } + const changeSigma = (e: any) => setSigma(parseFloat(e.target.value)); + const changeKernelSize = (e: any) => + setKernelSize(parseInt(e.target.value, 10)); - return ( -
- - - + const invalidSize = kernelSize % 2 !== 1 || kernelSize < 1 || kernelSize > 7; + const invalidConfig = !sigma || invalidSize; + return ( +
+
+ Sigma + changeSigma(e)} + /> + changeSigma(e)} + /> +
+
+ Kernel Size + changeKernelSize(e)} + /> + changeKernelSize(e)} + /> +
+ {invalidSize ? 'Enter an odd kernel size, between 1 and 7' : ''}
- ) -} +
+ +
+ ); +}; -const KernelConfig = (props: { onConfig: (kernelSize: number, sigma: number) => void, labelColor: string}) => { - const [kernelSize, setKernelSize] = useState(5); - const [sigma, setSigma] = useState(1); +type GaussianBlurDemoType = { + labelColor: string; + imgUrl: string; +}; - const changeSigma = (e: any) => setSigma(parseFloat(e.target.value)); - const changeKernelSize = (e: any) => setKernelSize(parseInt(e.target.value)); +const GaussianBlurDemo: React.FC = ({ + labelColor, + imgUrl, +}) => { + const [kernel, setKernel] = useState(undefined); + const [kernelGrid, setKernelGrid] = useState( + undefined, + ); - const invalidSize = (kernelSize % 2 !== 1 || kernelSize < 1 || kernelSize > 7) - const invalidConfig = !sigma || invalidSize; - return ( -
-
- Sigma - changeSigma(e)} /> - changeSigma(e)} /> -
-
- Kernel Size - changeKernelSize(e)} /> - changeKernelSize(e)} /> -
- { invalidSize ? 'Enter an odd kernel size, between 1 and 7' : ''} -
-
- -
- ); -} + const configureKernel = (kernelSize: number, sigma: number) => { + let newKernel: number[]; + if (kernelSize === 1) { + newKernel = [1]; + } else { + newKernel = generateGaussianKernel(kernelSize, sigma); + } + const newKernelGrid = newKernel.reduce((rslt: number[][], val, idx) => { + if (idx % kernelSize === 0) rslt.push([]); + rslt[rslt.length - 1].push(val); + return rslt; + }, []); + setKernel(newKernel); + setKernelGrid(newKernelGrid); + }; + return ( +
+ + + +
+ ); +}; -export default GaussianBlurDemo; \ No newline at end of file +export default GaussianBlurDemo; diff --git a/src/modules/computerVision/haarWavelet/HaarWaveletDemo.tsx b/src/modules/computerVision/haarWavelet/HaarWaveletDemo.tsx index 94c04f4..90e4e96 100644 --- a/src/modules/computerVision/haarWavelet/HaarWaveletDemo.tsx +++ b/src/modules/computerVision/haarWavelet/HaarWaveletDemo.tsx @@ -1,41 +1,59 @@ -import React, {useState} from 'react'; +import React, { useState } from 'react'; import InteractiveFilter from '../common/InteractiveFilter'; -import { haarFilter } from './haarTransform'; +import haarFilter from './haarTransform'; /* how does haar relate to normal kernel convolutions? What other configs/things to add to demo? currently not very intuitive */ -const HaarWaveletDemo = (props: {labelColor: string, imgUrl: string}) => { - const [recursions, setRecursions] = useState(3); +type HaarWaveletDemoType = { + labelColor: string; + imgUrl: string; +}; - const invalidConfig = recursions < 1 || recursions > 10; +const HaarWaveletDemo: React.FC = ({ + labelColor, + imgUrl, +}) => { + const [recursions, setRecursions] = useState(3); - return ( -
-
- Number of Recursions - setRecursions(parseInt(e.target.value))} /> - setRecursions(parseInt(e.target.value))} /> -
- { invalidConfig ? 'Enter an integer, between 1 and 10' : ''} -
-
- { - haarFilter(inCanvas, outCanvas, recursions); - }} - /> -
- ); + const invalidConfig = recursions < 1 || recursions > 10; + return ( +
+
+ Number of Recursions + setRecursions(parseInt(e.target.value, 10))} + /> + setRecursions(parseInt(e.target.value, 10))} + /> +
+ {invalidConfig ? 'Enter an integer, between 1 and 10' : ''} +
+
+ { + haarFilter(inCanvas, outCanvas, recursions); + }} + /> +
+ ); }; -export default HaarWaveletDemo; \ No newline at end of file +export default HaarWaveletDemo; diff --git a/src/modules/computerVision/haarWavelet/haarTransform.tsx b/src/modules/computerVision/haarWavelet/haarTransform.tsx index 2652165..a4e8b18 100644 --- a/src/modules/computerVision/haarWavelet/haarTransform.tsx +++ b/src/modules/computerVision/haarWavelet/haarTransform.tsx @@ -1,117 +1,130 @@ -export { haarFilter}; - +/* eslint-disable no-param-reassign */ // https://stevenbas.art/examples/ImageProcessing/ex4/ +function oneDHaarTransform(pixRow: number[]) { + let sum = 0; + let diff = 0; + const halfLen = pixRow.length / 2; + const tempHaar = []; + + // It only recurses on first half of the array + for (let i = 0; i < halfLen; i += 1) { + sum = pixRow[2 * i] + pixRow[2 * i + 1]; + sum /= Math.sqrt(2); + diff = pixRow[2 * i] - pixRow[2 * i + 1]; + diff /= Math.sqrt(2); + tempHaar[i] = sum; + tempHaar[i + halfLen] = diff; + } + for (let i = 0; i < pixRow.length; i += 1) { + pixRow[i] = tempHaar[i]; + } +} + /** * Applies the haar transformation to the image in `inCanvas`, and draws the output * on `outCanvas` - * - * @param inCanvas - * @param outCanvas + * + * @param inCanvas + * @param outCanvas * @param iterations how many recursions to do */ -function haarFilter(inCanvas: HTMLCanvasElement, outCanvas: HTMLCanvasElement, iterations: number) { - const inData = inCanvas.getContext("2d")?.getImageData(0,0, inCanvas.width, inCanvas.height); - const outData = outCanvas.getContext("2d")?.getImageData(0,0, outCanvas.width, outCanvas.height); - if (!inData || !outData) return; - - const inPix = inData.data; - const imgWidth = inCanvas.width; //should be the same for outCanvas - const imgHeight = inCanvas.height; - - // initialize array with original pix values - const haar :number[][][] = []; - for (let row = 0; row < imgHeight; row++) { - haar[row] = []; - for (let col = 0; col < imgWidth; col++) { - haar[row][col] = []; - for (let i = 0; i < 3; i++) { - haar[row][col][i] = inPix[4*(row*imgWidth + col + i)]; - } +function haarFilter( + inCanvas: HTMLCanvasElement, + outCanvas: HTMLCanvasElement, + iterations: number, +) { + const inData = inCanvas + .getContext('2d') + ?.getImageData(0, 0, inCanvas.width, inCanvas.height); + const outData = outCanvas + .getContext('2d') + ?.getImageData(0, 0, outCanvas.width, outCanvas.height); + if (!inData || !outData) return; + + const inPix = inData.data; + const imgWidth = inCanvas.width; // should be the same for outCanvas + const imgHeight = inCanvas.height; + + // initialize array with original pix values + const haar: number[][][] = []; + for (let row = 0; row < imgHeight; row += 1) { + haar[row] = []; + for (let col = 0; col < imgWidth; col += 1) { + haar[row][col] = []; + for (let i = 0; i < 3; i += 1) { + haar[row][col][i] = inPix[4 * (row * imgWidth + col + i)]; + } + } + } + + // Do a Haar Wavelet Transform + let currWidth = imgWidth; + let currHeight = imgHeight; + let haarRow = []; + while ((currWidth > 1 || currHeight > 1) && iterations > 1) { + iterations -= 1; + + // Do it for each row first + if (currWidth > 1) { + for (let row = 0; row < currHeight; row += 1) { + for (let i = 0; i < 3; i += 1) { + for (let col = 0; col < currWidth; col += 1) { + haarRow[col] = haar[row][col][i]; + } + + oneDHaarTransform(haarRow); + + for (let col = 0; col < currWidth; col += 1) { + haar[row][col][i] = haarRow[col]; + } } + } } - //Do a Haar Wavelet Transform - let currWidth = imgWidth; - let currHeight = imgHeight; - let haarRow = []; - while( (currWidth > 1 || currHeight > 1) && (iterations > 1) ) { - iterations = iterations -1; - - //Do it for each row first - if (currWidth > 1) { - for(let row = 0; row < currHeight; row++){ - for (let i = 0; i < 3; i++) { - for(let col = 0; col < currWidth; col++) { - haarRow[col] = haar[row][col][i]; - } - - oneDHaarTransform(haarRow); - - for(let col = 0; col < currWidth; col++) { - haar[row][col][i] = haarRow[col]; - } - } - } - } + // Then perform Haar transform on each column + haarRow = []; + if (currHeight > 1) { + for (let col = 0; col < currWidth; col += 1) { + for (let i = 0; i < 3; i += 1) { + for (let row = 0; row < currHeight; row += 1) { + haarRow[row] = haar[row][col][i]; + } - //Then perform Haar transform on each column - haarRow = []; - if (currHeight > 1) { - for(let col = 0; col < currWidth; col++) { - for (let i = 0; i < 3; i++) { - for(let row = 0; row < currHeight; row++) { - haarRow[row] = haar[row][col][i]; - } + oneDHaarTransform(haarRow); - oneDHaarTransform(haarRow); - - for(let row = 0; row < currHeight; row++) { - haar[row][col][i] = haarRow[row]; - } - } - } + for (let row = 0; row < currHeight; row += 1) { + haar[row][col][i] = haarRow[row]; + } } - haarRow = []; - - if (currHeight > 1) {currHeight = currHeight/2}; - if (currWidth > 1) {currWidth = currWidth/2}; + } } + haarRow = []; - //Copy pix data to canvas - const outPix = outData.data; - for (let row = 0; row < imgHeight; row++) { - for (let col = 0; col < imgWidth; col++) { - outPix[4*(row*imgWidth + col) ] = haar[row][col][0]; - outPix[4*(row*imgWidth + col)+1 ] = haar[row][col][1]; - - outPix[4*(row*imgWidth + col)+2 ] = haar[row][col][2]; - - outPix[4*(row*imgWidth + col)+3 ] = 255; - }; - }; - console.log(outData); - outCanvas.getContext("2d")?.putImageData(outData,0,0); -} - - -function oneDHaarTransform(pixRow: number[]) { - var sum = 0; - var diff = 0; - var halfLen = pixRow.length/2; - var tempHaar = []; - - //It only recurses on first half of the array - for (var i = 0; i < halfLen; i++) { - sum = pixRow[2*i] + pixRow[2*i + 1]; - sum = sum / Math.sqrt(2); - diff = pixRow[2*i] - pixRow[2*i + 1]; - diff = diff / Math.sqrt(2); - tempHaar[i] = sum; - tempHaar[i + halfLen] = diff + if (currHeight > 1) { + currHeight /= 2; } - for (var i = 0; i < pixRow.length; i++) { - pixRow[i] = tempHaar[i]; + if (currWidth > 1) { + currWidth /= 2; } -}; + } + + // Copy pix data to canvas + const outPix = outData.data; + for (let row = 0; row < imgHeight; row += 1) { + for (let col = 0; col < imgWidth; col += 1) { + // TODO: array destructuring + // eslint-disable-next-line + outPix[4 * (row * imgWidth + col)] = haar[row][col][0]; + // eslint-disable-next-line + outPix[4 * (row * imgWidth + col) + 1] = haar[row][col][1]; + // eslint-disable-next-line + outPix[4 * (row * imgWidth + col) + 2] = haar[row][col][2]; + // eslint-disable-next-line + outPix[4 * (row * imgWidth + col) + 3] = 255; + } + } + outCanvas.getContext('2d')?.putImageData(outData, 0, 0); +} +export default haarFilter; diff --git a/src/modules/computerVision/imageSelector/ImageSelectableDemo.tsx b/src/modules/computerVision/imageSelector/ImageSelectableDemo.tsx index 3ba886a..136af7f 100644 --- a/src/modules/computerVision/imageSelector/ImageSelectableDemo.tsx +++ b/src/modules/computerVision/imageSelector/ImageSelectableDemo.tsx @@ -1,41 +1,43 @@ -import React, {useState} from 'react'; +import React, { useState } from 'react'; import ImageSelector from './ImageSelector'; export interface DemoProps { - imgUrl: string, - labelColor: string, - [arg: string]: any + imgUrl: string; + labelColor: string; + [arg: string]: any; } export interface ImageSelectableDemoProps { - initImg: string, - Demo: React.ComponentType, - demoProps: {labelColor: string} + initImg: string; + Demo: React.ComponentType; + demoProps: { labelColor: string }; } /** - * - * @param props - * @param props.initImg the initial image that the demo should use, a string for the image filename + * + * @param props + * @param props.initImg the initial image that the demo should use, a string for the image filename * (including extension, without filepath) * @param props.Demo react component for the demo - * @param props.demoProps object containing any other props that the demo needs + * @param props.demoProps object containing any other props that the demo needs */ -export const ImageSelectableDemo = ({initImg, Demo, demoProps} : ImageSelectableDemoProps) => { - const [imgName, setImgName] = useState(initImg); - const [imgUrl, setImgUrl] = useState(''); - - const onImgChange = (img: string, imgUrl: string) => { - setImgName(img); - setImgUrl(imgUrl); - } - - return ( -
- - -
- ); -} +export const ImageSelectableDemo = ({ + initImg, + Demo, + demoProps, +}: ImageSelectableDemoProps) => { + const [imgName, setImgName] = useState(initImg); + const [imgUrl, setImgUrl] = useState(''); + const onImgChange = (img: string, url: string) => { + setImgName(img); + setImgUrl(url); + }; + return ( +
+ + +
+ ); +}; diff --git a/src/modules/computerVision/imageSelector/ImageSelector.tsx b/src/modules/computerVision/imageSelector/ImageSelector.tsx index 2a279de..81615c1 100644 --- a/src/modules/computerVision/imageSelector/ImageSelector.tsx +++ b/src/modules/computerVision/imageSelector/ImageSelector.tsx @@ -1,46 +1,58 @@ +/* eslint-disable global-require */ import React, { useEffect } from 'react'; import './ImageSelector.css'; -const ImageSelector = (props: { currImg: string, onSelect: (img: string, imgUrl: string) => any }) => { - useEffect(() => props.onSelect(props.currImg, ALL_IMGS[props.currImg]), - []); - - const makeImg = (key: string) => ( - props.onSelect(key, ALL_IMGS[key])} - /> - ) - - return ( -
- Select Image -
- {Object.keys(ALL_IMGS).map(key => { - return ALL_IMGS[key] && makeImg(key); - } - )} -
-
- ); -} +const ALL_IMGS: { [name: string]: any } = { + 'three.png': require('../../../media/modules/computerVision/imageLibrary/three.png') + .default, + 'diamond.png': require('../../../media/modules/computerVision/imageLibrary/diamond.png') + .default, + 'square.png': require('../../../media/modules/computerVision/imageLibrary/square.png') + .default, + 'circles.jpg': require('../../../media/modules/computerVision/imageLibrary/circles.jpg') + .default, + 'dogSilhouette.jpg': require('../../../media/modules/computerVision/imageLibrary/dogSilhouette.jpg') + .default, + 'purpleFlowers.jpeg': require('../../../media/modules/computerVision/imageLibrary/purpleFlowers.jpeg') + .default, + 'steps.png': require('../../../media/modules/computerVision/imageLibrary/steps.png') + .default, + 'tabbyCat.jpg': require('../../../media/modules/computerVision/imageLibrary/tabbyCat.jpg') + .default, + 'teddyBear.jpg': require('../../../media/modules/computerVision/imageLibrary/teddyBear.jpg') + .default, + 'zebra.jpg': require('../../../media/modules/computerVision/imageLibrary/zebra.jpg') + .default, + 'bwWoman.jpg': require('../../../media/modules/computerVision/imageLibrary/bwWoman.jpg') + .default, + 'bwMan.jpg': require('../../../media/modules/computerVision/imageLibrary/bwMan.jpg') + .default, +}; +const ImageSelector = (props: { + currImg: string; + onSelect: (img: string, imgUrl: string) => any; +}) => { + useEffect(() => props.onSelect(props.currImg, ALL_IMGS[props.currImg]), []); + const makeImg = (key: string) => ( + // eslint-disable-next-line + props.onSelect(key, ALL_IMGS[key])} + /> + ); -const ALL_IMGS: { [name: string]: any } = { - 'three.png': require('../../../media/modules/computerVision/imageLibrary/three.png').default, - 'diamond.png': require('../../../media/modules/computerVision/imageLibrary/diamond.png').default, - 'square.png': require('../../../media/modules/computerVision/imageLibrary/square.png').default, - 'circles.jpg': require('../../../media/modules/computerVision/imageLibrary/circles.jpg').default, - 'dogSilhouette.jpg': require('../../../media/modules/computerVision/imageLibrary/dogSilhouette.jpg').default, - 'purpleFlowers.jpeg': require('../../../media/modules/computerVision/imageLibrary/purpleFlowers.jpeg').default, - 'steps.png': require('../../../media/modules/computerVision/imageLibrary/steps.png').default, - 'tabbyCat.jpg': require('../../../media/modules/computerVision/imageLibrary/tabbyCat.jpg').default, - 'teddyBear.jpg': require('../../../media/modules/computerVision/imageLibrary/teddyBear.jpg').default, - 'zebra.jpg': require('../../../media/modules/computerVision/imageLibrary/zebra.jpg').default, - 'bwWoman.jpg': require('../../../media/modules/computerVision/imageLibrary/bwWoman.jpg').default, - 'bwMan.jpg': require('../../../media/modules/computerVision/imageLibrary/bwMan.jpg').default -} + return ( +
+ Select Image +
+ {Object.keys(ALL_IMGS).map(key => ALL_IMGS[key] && makeImg(key))} +
+
+ ); +}; export default ImageSelector; diff --git a/src/modules/stateSpaces/common/BasicScatter.tsx b/src/modules/stateSpaces/common/BasicScatter.tsx index 10e45fa..ec3b5b9 100644 --- a/src/modules/stateSpaces/common/BasicScatter.tsx +++ b/src/modules/stateSpaces/common/BasicScatter.tsx @@ -4,48 +4,79 @@ import { Scatter } from 'react-chartjs-2'; export type { DataSeriesMap, ColorMap }; export { BasicScatter }; -type DataSeriesMap = { [dataClass: string]: Array<{ x: number, y: number }> }; +type DataSeriesMap = { [dataClass: string]: Array<{ x: number; y: number }> }; type ColorMap = { [dataClass: string]: string }; -const BasicScatter = - (props: { points: DataSeriesMap, xLabel: string, yLabel: string, colorMap: ColorMap, labelColorHex: string}) => { - const data: { datasets: Object[] } = { datasets: [] }; - Object.entries(props.points).forEach(([dataClass, classPoints]) => { - data.datasets.push({ - label: dataClass, - fill: true, - pointRadius: 4, - backgroundColor: props.colorMap[dataClass], - data: classPoints - }); - }) - const options = { - showLines: false, - tooltips: { enabled: false }, - scales: { - yAxes: [{ - scaleLabel: { display: true, labelString: props.yLabel, fontSize: 16, fontFamily: 'open sans', fontStyle: 'italic bold', fontColor: props.labelColorHex }, - gridLines: {lineWidth: 3, color: '#8D9DBA'}, - ticks: {fontColor: '#394D73'} - }], - xAxes: [{ - scaleLabel: { display: true, labelString: props.xLabel, fontSize: 16, fontFamily: 'open sans', fontStyle: 'italic bold', fontColor: props.labelColorHex }, - gridLines: {lineWidth: 3, color: '#8D9DBA'}, - ticks: {fontColor: '#394D73'} - }], - }, - legend: { - labels: { - fontSize: 14, - fontFamily: 'open sans', - fontStyle: 'bold', - fontColor: props.labelColorHex - } - } - }; - return ( -
- -
- ); - }; +type BasicScatterType = { + points: DataSeriesMap; + xLabel: string; + yLabel: string; + colorMap: ColorMap; + labelColorHex: string; +}; + +const BasicScatter: React.FC = ({ + points, + xLabel, + yLabel, + colorMap, + labelColorHex, +}) => { + const data: { datasets: Object[] } = { datasets: [] }; + Object.entries(points).forEach(([dataClass, classPoints]) => { + data.datasets.push({ + label: dataClass, + fill: true, + pointRadius: 4, + backgroundColor: colorMap[dataClass], + data: classPoints, + }); + }); + const options = { + showLines: false, + tooltips: { enabled: false }, + scales: { + yAxes: [ + { + scaleLabel: { + display: true, + labelString: yLabel, + fontSize: 16, + fontFamily: 'open sans', + fontStyle: 'italic bold', + fontColor: labelColorHex, + }, + gridLines: { lineWidth: 3, color: '#8D9DBA' }, + ticks: { fontColor: '#394D73' }, + }, + ], + xAxes: [ + { + scaleLabel: { + display: true, + labelString: xLabel, + fontSize: 16, + fontFamily: 'open sans', + fontStyle: 'italic bold', + fontColor: labelColorHex, + }, + gridLines: { lineWidth: 3, color: '#8D9DBA' }, + ticks: { fontColor: '#394D73' }, + }, + ], + }, + legend: { + labels: { + fontSize: 14, + fontFamily: 'open sans', + fontStyle: 'bold', + fontColor: labelColorHex, + }, + }, + }; + return ( +
+ +
+ ); +}; diff --git a/src/modules/stateSpaces/kmeans/index.ts b/src/modules/stateSpaces/kmeans/index.ts index 6a768b5..ff5210e 100644 --- a/src/modules/stateSpaces/kmeans/index.ts +++ b/src/modules/stateSpaces/kmeans/index.ts @@ -3,5 +3,5 @@ import KMeansStepExample from './kmeansStepExample'; import KMeansDemo from './kmeans'; -export {InteractiveClusteringExample, KMeansStepExample}; +export { InteractiveClusteringExample, KMeansStepExample }; export default KMeansDemo; diff --git a/src/modules/stateSpaces/kmeans/interactiveClusteringExample.tsx b/src/modules/stateSpaces/kmeans/interactiveClusteringExample.tsx index a452c21..945d477 100644 --- a/src/modules/stateSpaces/kmeans/interactiveClusteringExample.tsx +++ b/src/modules/stateSpaces/kmeans/interactiveClusteringExample.tsx @@ -1,313 +1,413 @@ +/* eslint-disable react/no-this-in-sfc */ +/* eslint-disable no-underscore-dangle */ +// must disable due to referencing the inside of the chart import React, { useState } from 'react'; +import dragData from 'chartjs-plugin-dragdata'; +import { Scatter } from 'react-chartjs-2'; +import kmeans from 'ml-kmeans'; import trainData from './train.json'; import trainDataIris from './iris.json'; import trainDataIris2 from './iris2.json'; import titanicData from './titanic.json'; - -import dragData from 'chartjs-plugin-dragdata'; -import { Scatter } from 'react-chartjs-2'; -import kmeans from 'ml-kmeans'; -import './chartjs-plugin-dragdata.d.ts'; - -import {organiseData, InputData, AddedPointList, PointToRemove, PointToRemoveList, BubbleDataEntry, processdata, AddedPoint, KMeansResult} from './utils'; +import './chartjs-plugin-dragdata.d'; + +import { + organiseData, + InputData, + AddedPointList, + PointToRemove, + PointToRemoveList, + BubbleDataEntry, + processdata, + AddedPoint, + KMeansResult, +} from './utils'; type InteractiveClusteringExampleType = { - hidden: boolean, - yLabel?: string, - xLabel?: string - k?: number, - centersList?: number[][][], - trainingDatasets?: InputData[][], + hidden: boolean; + yLabel?: string; + xLabel?: string; + k?: number; + centersList?: number[][][]; + trainingDatasets?: InputData[][]; }; const InteractiveClusteringExample: React.FC = ({ - hidden = false, - xLabel = '', - yLabel = '', - k = 2, - // 0 == original data - // 1 == iris data - // 2 == diff iris data - // 3 == titanic data - // change to an int if more datasets - trainingDatasets = [trainData, trainDataIris, trainDataIris2, titanicData], - centersList = [ - [[0, 0], [50, 50]], - [[2, 2], [7, 5]], - [[20, 20], [40, 40]], - [[10, 10], [40, 40]], + hidden = false, + xLabel = '', + yLabel = '', + k = 2, + // 0 == original data + // 1 == iris data + // 2 == diff iris data + // 3 == titanic data + // change to an int if more datasets + trainingDatasets = [trainData, trainDataIris, trainDataIris2, titanicData], + centersList = [ + [ + [0, 0], + [50, 50], ], + [ + [2, 2], + [7, 5], + ], + [ + [20, 20], + [40, 40], + ], + [ + [10, 10], + [40, 40], + ], + ], }) => { - - let organizedDatasets = []; - for(const dataset of trainingDatasets) { - organizedDatasets.push(organiseData(dataset)); - }; - - let kmeansAnswers: KMeansResult[] = []; - for (let i = 0; i < trainingDatasets.length; ++i) { - kmeansAnswers.push(kmeans(organizedDatasets[i], k, { initialization: centersList[i], maxIterations: 1 }, )); + const organizedDatasets = []; + // TODO + // eslint-disable-next-line + for (const dataset of trainingDatasets) { + organizedDatasets.push(organiseData(dataset)); + } + + const kmeansAnswers: KMeansResult[] = []; + for (let i = 0; i < trainingDatasets.length; i += 1) { + kmeansAnswers.push( + kmeans(organizedDatasets[i], k, { + initialization: centersList[i], + maxIterations: 1, + }), + ); + } + + const [originalDataset, setO] = useState(0); + + const centersx = kmeansAnswers[originalDataset].centroids; + + // in order to make the chart updateable after moving a center + const [x1Idx, setX1Idx] = useState(centersx[0].centroid[0]); + const [y1Idx, setY1Idx] = useState(centersx[0].centroid[1]); + const [x2Idx, setX2Idx] = useState(centersx[1].centroid[0]); + const [y2Idx, setY2Idx] = useState(centersx[1].centroid[1]); + + const [addedPoints, setAP]: AddedPointList = useState([[], [], [], []]); + const addPoint = (index: number, newPoint: AddedPoint) => { + const newAddedPoints: AddedPoint[][] = [...addedPoints]; + newAddedPoints[index] = newAddedPoints[index].concat(newPoint); + setAP(newAddedPoints); + }; + + const [pointsToRemove, setRT]: PointToRemoveList = useState([[], [], [], []]); + const addPointToRemove = (index: number, newPoint: PointToRemove) => { + const newPoints: PointToRemove[][] = [...pointsToRemove]; + newPoints[index] = newPoints[index].concat(newPoint); + setRT(newPoints); + }; + + const [percentRemove, setPR] = useState(16); + const [editable, setEdit] = useState(true); + const [base, setBase] = useState(true); + + const changeO = (nextDataset: number) => { + setX1Idx(kmeansAnswers[nextDataset].centroids[0].centroid[0]); + setY1Idx(kmeansAnswers[nextDataset].centroids[0].centroid[1]); + setX2Idx(kmeansAnswers[nextDataset].centroids[1].centroid[0]); + setY2Idx(kmeansAnswers[nextDataset].centroids[1].centroid[1]); + + setO(nextDataset); + }; + + let trainData2: InputData[] = trainingDatasets[originalDataset].slice(); + + // Remove a percentage of the data + if (originalDataset === 0) { + for (let i = trainData2.length; i > 0; i -= 1) { + if (i % 20 === 0) { + trainData2.splice(i, percentRemove); + } } - - const [originalDataset, setO] = useState(0); - - const changeO = (nextDataset: number) => { - setX1Idx(kmeansAnswers[nextDataset]['centroids'][0].centroid[0]); - setY1Idx(kmeansAnswers[nextDataset]['centroids'][0].centroid[1]); - setX2Idx(kmeansAnswers[nextDataset]['centroids'][1].centroid[0]); - setY2Idx(kmeansAnswers[nextDataset]['centroids'][1].centroid[1]); - - setO(nextDataset); + } else { + for (let i = trainData2.length; i > 0; i -= 1) { + if (i % 4 === 0) { + trainData2.splice(i, percentRemove - 16); + } } - - const centersx = kmeansAnswers[originalDataset]['centroids']; - - // in order to make the chart updateable after moving a center - const [x1Idx, setX1Idx] = useState(centersx[0].centroid[0]); - const [y1Idx, setY1Idx] = useState(centersx[0].centroid[1]); - const [x2Idx, setX2Idx] = useState(centersx[1].centroid[0]); - const [y2Idx, setY2Idx] = useState(centersx[1].centroid[1]); - - const [addedPoints, setAP]:AddedPointList = useState([[], [], [], []]); - const addPoint = (index: number, newPoint: AddedPoint) => { - let newAddedPoints: AddedPoint[][] = [...addedPoints]; - newAddedPoints[index] = newAddedPoints[index].concat(newPoint); - setAP(newAddedPoints); + } + + trainData2 = base + ? trainData2.concat(addedPoints[originalDataset]) + : addedPoints[originalDataset]; + + // where our data is going to be, 'bubble data' + const bubData: BubbleDataEntry[] = []; + + // possible edge case: if one dataset has fewer than 2 points, need fake data for kmeans + // as users can remove datapoints this is necessary + const fakepoints = [ + { Distance_Feature: 2, Speeding_Feature: 2 }, + { Distance_Feature: 1, Speeding_Feature: 1 }, + ]; + + // format needed for kmeans() + const c2 = [ + [x1Idx, y1Idx], + [x2Idx, y2Idx], + ]; + + if (trainData2.length >= 2) { + const ansX = kmeans(organiseData(trainData2), k, { + initialization: c2, + maxIterations: 1, + }); + const data3 = organiseData(trainData2); + processdata(bubData, ansX.clusters, c2, hidden, data3, k); + } else { + const s = trainData2.concat(fakepoints); + const ansX = kmeans(organiseData(s), k, { + initialization: c2, + maxIterations: 1, + }); + const data3 = organiseData(trainData2); + const clustersss = trainData2.length === 1 ? [ansX.clusters[0]] : []; + processdata(bubData, clustersss, c2, hidden, data3, k); + } + + // data that will be put into the chart + const data: { datasets: BubbleDataEntry[] } = { datasets: [] }; + + Object.entries(bubData).forEach(cluster => { + data.datasets.push(cluster[1]); + }); + + // remove removethese from data + // TODO + // eslint-disable-next-line + for (const removethese of pointsToRemove) { + for (let i = 0; i < removethese.length; i += 1) { + data.datasets[removethese[i].dsIndex].data.splice(removethese[i].ind, 1); } - - const [pointsToRemove, setRT]: PointToRemoveList = useState([[], [], [], []]); - const addPointToRemove = (index: number, newPoint: PointToRemove) => { - let newPoints: PointToRemove[][] = [...pointsToRemove]; - newPoints[index] = newPoints[index].concat(newPoint); - setRT(newPoints); + } + + const onDragEnd = ( + e: React.ChangeEvent, + datasetIndex: number, + index: number, + value: { x: number; y: number }, + ) => { + if (!e) return; + if (datasetIndex === 0) { + setX1Idx(value.x); + setY1Idx(value.y); } - - const [percentRemove, setPR] = useState(16); - const [editable, setEdit] = useState(true); - const [base, setBase] = useState(true); - - let trainData2:InputData[] = trainingDatasets[originalDataset].slice(); - - // Remove a percentage of the data - if (originalDataset === 0) { - for (let i = trainData2.length; i > 0; i--) { - if (i % 20 === 0) { - trainData2.splice(i, percentRemove) - } - } + if (datasetIndex === 1) { + setX2Idx(value.x); + setY2Idx(value.y); } - else { - for (let i = trainData2.length; i > 0; i--) { - if (i % 4 === 0) { - trainData2.splice(i, percentRemove - 16) - } + }; + + // index corresponds to the datasets as numbered above + const yAxisMin: number[] = [0, 1, 0, 0]; + const yAxisMax: number[] = [120, 7, 40, 100]; + const xAxisMin: number[] = [0, 1, 0, 0]; + const xAxisMax: number[] = [250, 10, 100, 100]; + + const options = { + showLines: false, + tooltips: { enabled: false }, + scales: { + yAxes: [ + { + scaleLabel: { + display: true, + labelString: yLabel, + fontSize: 16, + fontFamily: 'open sans', + fontStyle: 'italic bold', + fontColor: '#CBD9F2', + }, + gridLines: { lineWidth: 3, color: '#8D9DBA' }, + ticks: { + fontColor: '#CBD9F2', + beginAtZero: true, + min: yAxisMin[originalDataset], + max: yAxisMax[originalDataset], + }, + }, + ], + xAxes: [ + { + scaleLabel: { + display: true, + labelString: xLabel, + fontSize: 16, + fontFamily: 'open sans', + fontStyle: 'italic bold', + fontColor: '#CBD9F2', + }, + gridLines: { lineWidth: 3, color: '#8D9DBA' }, + ticks: { + fontColor: '#CBD9F2', + beginAtZero: true, + min: xAxisMin[originalDataset], + max: xAxisMax[originalDataset], + }, + }, + ], + }, + legend: { + labels: { + fontSize: 14, + fontFamily: 'arial', + fontStyle: 'bold', + fontColor: '#CBD9F2', + }, + }, + dragData: true, + dragX: true, + dragDataRound: 0, + onClick(evt: MouseEvent) { + if (editable) { + // all the // @ts-ignore 's from here on are due to the fact that we can't access of 'this' until onClick is called + // inside the react component + // @ts-ignore + const asdgwg = this.chart.getElementAtEvent(evt)[0]; + + // @ts-ignore + const yTop = this.chartArea.top; + // @ts-ignore + const yBottom = this.chartArea.bottom; + // @ts-ignore + const yMin = this.scales['y-axis-1'].min; + // @ts-ignore + const yMax = this.scales['y-axis-1'].max; + let newY = 0; + + if (evt.offsetY <= yBottom && evt.offsetY >= yTop) { + newY = Math.abs((evt.offsetY - yTop) / (yBottom - yTop)); + newY = (newY - 1) * -1; + newY = newY * Math.abs(yMax - yMin) + yMin; } - } - - trainData2 = base ? trainData2.concat(addedPoints[originalDataset]) : addedPoints[originalDataset]; - - // where our data is going to be, 'bubble data' - let bubData: BubbleDataEntry[] = []; - - // possible edge case: if one dataset has fewer than 2 points, need fake data for kmeans - // as users can remove datapoints this is necessary - const fakepoints = [{ Distance_Feature: 2, Speeding_Feature: 2 }, - { Distance_Feature: 1, Speeding_Feature: 1 }]; - - // format needed for kmeans() - const c2 = [[x1Idx, y1Idx], [x2Idx, y2Idx]]; - - if (trainData2.length >= 2) { - const ans_x = kmeans(organiseData(trainData2), k, { initialization: c2, maxIterations: 1 }, ); - const data3 = organiseData(trainData2); - processdata(bubData, ans_x.clusters, c2, hidden, data3, k); - } - else { - const s = trainData2.concat(fakepoints); - const ans_x = kmeans(organiseData(s), k, { initialization: c2, maxIterations: 1 }, ); - const data3 = organiseData(trainData2) - const clustersss = trainData2.length === 1 ? [ans_x.clusters[0]] : []; - processdata(bubData, clustersss, c2, hidden, data3, k); - } - - // data that will be put into the chart - const data:{datasets: BubbleDataEntry[]} = { datasets : [] }; - - Object.entries(bubData).forEach((cluster) => { - data.datasets.push(cluster[1]); - }); - - // remove removethese from data - for (const removethese of pointsToRemove) { - for (let i = 0; i < removethese.length; i++) { - data.datasets[removethese[i].ds_index].data.splice(removethese[i].ind, 1); + // @ts-ignore + const xTop = this.chartArea.left; + // @ts-ignore + const xBottom = this.chartArea.right; + // @ts-ignore + const xMin = this.scales['x-axis-1'].min; + // @ts-ignore + const xMax = this.scales['x-axis-1'].max; + let newX = 0; + + if (evt.offsetX <= xBottom && evt.offsetX >= xTop) { + newX = Math.abs((evt.offsetX - xTop) / (xBottom - xTop)); + newX = newX * Math.abs(xMax - xMin) + xMin; } - } - const onDragEnd = (e: React.ChangeEvent, datasetIndex: number, index: number, value: {x: number, y: number}) => { - if (!e) return; - if (datasetIndex === 0) { - setX1Idx(value.x); - setY1Idx(value.y); - } - if (datasetIndex === 1) { - setX2Idx(value.x); - setY2Idx(value.y); + // checking to make sure where you click isnt on the centroids + // dont want to remove those + const rad = 7; + const inXBounds = + (newX < x1Idx + rad && newX > x1Idx - rad) || + (newX < x2Idx + rad && newX > x2Idx - rad); + const inYBounds = + (newY < y1Idx + rad && newY > y1Idx - rad) || + (newY < y2Idx + rad && newY > y2Idx - rad); + + const onCentroid = inXBounds && inYBounds; + + if (asdgwg && !onCentroid) { + const dsIndex = asdgwg._datasetIndex; + const ind = asdgwg._index; + + addPointToRemove(originalDataset, { dsIndex, ind }); + + // @ts-ignore + setX1Idx(this.chart.data.datasets[0].data[0].x + 0.1); + // @ts-ignore + setX1Idx(this.chart.data.datasets[0].data[0].x - 0.1); + } else if (newX > 0 && newY > 0) { + const point = { Distance_Feature: newX, Speeding_Feature: newY }; + addPoint(originalDataset, point); + + // forces the chart to update because it won't rerender otherwise + // @ts-ignore + setX1Idx(this.chart.data.datasets[0].data[0].x + 0.1); + // @ts-ignore + setX1Idx(this.chart.data.datasets[0].data[0].x - 0.1); } - } - - // index corresponds to the datasets as numbered above - const yAxisMin: number[] = [0, 1, 0, 0]; - const yAxisMax: number[] = [120, 7, 40, 100]; - const xAxisMin: number[] = [0, 1, 0, 0]; - const xAxisMax: number[] = [250, 10, 100, 100]; - - const options = { - showLines: false, - tooltips: { enabled: false }, - scales: { - yAxes: [{ - scaleLabel: { display: true, labelString: yLabel, fontSize: 16, fontFamily: 'open sans', fontStyle: 'italic bold', fontColor: "#CBD9F2" }, - gridLines: {lineWidth: 3, color: '#8D9DBA'}, - ticks: { - fontColor: '#CBD9F2', - beginAtZero: true, - min: yAxisMin[originalDataset], - max: yAxisMax[originalDataset], - } - }], - xAxes: [{ - scaleLabel: { display: true, labelString: xLabel, fontSize: 16, fontFamily: 'open sans', fontStyle: 'italic bold', fontColor: "#CBD9F2" }, - gridLines: {lineWidth: 3, color: '#8D9DBA'}, - ticks: { - fontColor: '#CBD9F2', - beginAtZero: true, - min: xAxisMin[originalDataset], - max: xAxisMax[originalDataset], - } - }], - }, - legend: { - labels: { - fontSize: 14, - fontFamily: 'arial', - fontStyle: 'bold', - fontColor: "#CBD9F2" - } - }, - dragData: true, - dragX: true, - dragDataRound: 0, - onClick : function (evt: MouseEvent) { - if (editable) { - // all the // @ts-ignore 's from here on are due to the fact that we can't access of 'this' until onClick is called - // inside the react component - // @ts-ignore - const asdgwg = this.chart.getElementAtEvent(evt)[0]; - - // @ts-ignore - let yTop = this.chartArea.top; - // @ts-ignore - let yBottom = this.chartArea.bottom; - // @ts-ignore - let yMin = this.scales['y-axis-1'].min; - // @ts-ignore - let yMax = this.scales['y-axis-1'].max; - let newY = 0; - - if (evt.offsetY <= yBottom && evt.offsetY >= yTop) { - newY = Math.abs((evt.offsetY - yTop) / (yBottom - yTop)); - newY = (newY - 1) * -1; - newY = newY * (Math.abs(yMax - yMin)) + yMin; - }; - // @ts-ignore - let xTop = this.chartArea.left; - // @ts-ignore - let xBottom = this.chartArea.right; - // @ts-ignore - let xMin = this.scales['x-axis-1'].min; - // @ts-ignore - let xMax = this.scales['x-axis-1'].max; - let newX = 0; - - if (evt.offsetX <= xBottom && evt.offsetX >= xTop) { - newX = Math.abs((evt.offsetX - xTop) / (xBottom - xTop)); - newX = newX * (Math.abs(xMax - xMin)) + xMin; - }; - - // checking to make sure where you click isnt on the centroids - // dont want to remove those - const rad = 7 - const inXBounds = ((newX < x1Idx + rad) && (newX > x1Idx - rad)) || ((newX < x2Idx + rad) && (newX > x2Idx - rad)) - const inYBounds = ((newY < y1Idx + rad) && (newY > y1Idx - rad)) || ((newY < y2Idx + rad) && (newY > y2Idx - rad)) - - const onCentroid = inXBounds && inYBounds - - if (asdgwg && !onCentroid) { - let ds_index = asdgwg._datasetIndex - let ind = asdgwg._index - - - addPointToRemove(originalDataset, {ds_index, ind}); - - // @ts-ignore - setX1Idx(this.chart.data.datasets[0].data[0].x + 0.1); - // @ts-ignore - setX1Idx(this.chart.data.datasets[0].data[0].x - 0.1); - return; - } - else { - - if (newX > 0 && newY > 0) { - - const point = {Distance_Feature: newX, Speeding_Feature: newY}; - addPoint(originalDataset, point); - - // forces the chart to update because it won't rerender otherwise - // @ts-ignore - setX1Idx(this.chart.data.datasets[0].data[0].x + 0.1) - // @ts-ignore - setX1Idx(this.chart.data.datasets[0].data[0].x - 0.1) - } - - } - } - }, - - onDragEnd, - onDragStart:onDragEnd, - onDrag:onDragEnd, - animation: { - duration: 0 - }, - }; - - const datasetLabel = [ - "Original Dataset", - "Iris Sepal Dataset", - "Iris Petal Dataset", - "Titanic Dataset", - ]; - - return ( -
-
- -
-
-
- - - -
-
- - - -
-
-
); + } + }, + + onDragEnd, + onDragStart: onDragEnd, + onDrag: onDragEnd, + animation: { + duration: 0, + }, + }; + + const datasetLabel = [ + 'Original Dataset', + 'Iris Sepal Dataset', + 'Iris Petal Dataset', + 'Titanic Dataset', + ]; + + return ( +
+
+ +
+
+
+ + + +
+
+ + + +
+
+
+ ); }; export default InteractiveClusteringExample; diff --git a/src/modules/stateSpaces/kmeans/kmeans.tsx b/src/modules/stateSpaces/kmeans/kmeans.tsx index 3ed286d..976f38f 100644 --- a/src/modules/stateSpaces/kmeans/kmeans.tsx +++ b/src/modules/stateSpaces/kmeans/kmeans.tsx @@ -1,95 +1,102 @@ import React from 'react'; -import trainData from './train.json'; - import { Scatter } from 'react-chartjs-2'; +import trainData from './train.json'; -import { BubbleDataEntry, ScatterData, NewClusterType, cluster_colors } from './utils'; +import { + BubbleDataEntry, + ScatterData, + NewClusterType, + clusterColors, +} from './utils'; import InteractiveClusteringExample from './interactiveClusteringExample'; import KMeansStepExample from './kmeansStepExample'; // Currently unused, may be out of date -type BubbleDataScatterType = {graphdata: BubbleDataEntry[]}; -const BubbleDataScatter: React.FC = ({graphdata}) => { - const scatterData:ScatterData = { datasets : [{ - data: [] - }]}; - - // was bubbleData as defined in app - Object.entries(graphdata).forEach((cluster) => { - Object.entries(cluster[1].data).forEach((point) => { - scatterData.datasets[0].data.push({ - x: point[1].x, - y: point[1].y, - pointRadius: 15, - backgroundColor: '#ef5675', - }); +type BubbleDataScatterType = { graphdata: BubbleDataEntry[] }; +const BubbleDataScatter: React.FC = ({ graphdata }) => { + const scatterData: ScatterData = { + datasets: [ + { + data: [], + }, + ], + }; - }); - }) + // was bubbleData as defined in app + Object.entries(graphdata).forEach(cluster => { + Object.entries(cluster[1].data).forEach(point => { + scatterData.datasets[0].data.push({ + x: point[1].x, + y: point[1].y, + pointRadius: 15, + backgroundColor: '#ef5675', + }); + }); + }); - const options = { - showLines: false, - tooltips: { enabled: false }, - scales: { - yAxes: [{ - scaleLabel: { display: true } - }], - xAxes: [{ - scaleLabel: { display: true } - }], - } - }; - return (); - }; + const options = { + showLines: false, + tooltips: { enabled: false }, + scales: { + yAxes: [ + { + scaleLabel: { display: true }, + }, + ], + xAxes: [ + { + scaleLabel: { display: true }, + }, + ], + }, + }; + return ; +}; /* Working example: for debugging */ const App = () => { - const bubbleData:BubbleDataEntry[] = []; - - // processing for first chart - // (convert from json to more agreeable format) - for(let ci = 0; ci < 1; ci++) { - const newCluster:NewClusterType[] = []; - for (let ri = 0; ri < trainData.length; ri++) { - - newCluster.push({ - x: trainData[ri].Distance_Feature, - y: trainData[ri].Speeding_Feature, - r: 3 - }) + const bubbleData: BubbleDataEntry[] = []; - } - let colour = cluster_colors[ci]; - bubbleData.push({ - label: [`cluster #${ci}`], - backgroundColor: colour, - borderColor: colour, - data: newCluster, - pointRadius: 5, - }); + // processing for first chart + // (convert from json to more agreeable format) + for (let ci = 0; ci < 1; ci += 1) { + const newCluster: NewClusterType[] = []; + for (let ri = 0; ri < trainData.length; ri += 1) { + newCluster.push({ + x: trainData[ri].Distance_Feature, + y: trainData[ri].Speeding_Feature, + r: 3, + }); } + const colour = clusterColors[ci]; + bubbleData.push({ + label: [`cluster #${ci}`], + backgroundColor: colour, + borderColor: colour, + data: newCluster, + pointRadius: 5, + }); + } - return ( -
-
- -
-
-
-
-
-

- sample text -

-
-
-
- ); + return ( +
+
+ +
+
+
+
+
+

sample text

+
+
+
+ ); }; export default App; diff --git a/src/modules/stateSpaces/kmeans/kmeansStepExample.tsx b/src/modules/stateSpaces/kmeans/kmeansStepExample.tsx index 57ca805..33fcfe8 100644 --- a/src/modules/stateSpaces/kmeans/kmeansStepExample.tsx +++ b/src/modules/stateSpaces/kmeans/kmeansStepExample.tsx @@ -1,152 +1,226 @@ import React, { useState } from 'react'; +import { Scatter } from 'react-chartjs-2'; +import kmeans from 'ml-kmeans'; import trainData from './train.json'; import trainDataIris from './iris.json'; import trainDataIris2 from './iris2.json'; -import {InputData, organiseData, KMeansResult, BubbleDataEntry, getClasses, processdata} from './utils'; - -import { Scatter } from 'react-chartjs-2'; -import kmeans from 'ml-kmeans'; +import { + InputData, + organiseData, + KMeansResult, + BubbleDataEntry, + getClasses, + processdata, +} from './utils'; type KMeansStepExampleType = { - hidden: boolean, - xLabel?: string, - yLabel?: string, - k?: number, - trainingData?: InputData[], - trainingDataIris?: InputData[], - trainingDataIris2?: InputData[], - centers?: number[][], - centersIris?: number[][], - centersIris2?: number[][], + hidden: boolean; + xLabel?: string; + yLabel?: string; + k?: number; + trainingData?: InputData[]; + trainingDataIris?: InputData[]; + trainingDataIris2?: InputData[]; + centers?: number[][]; + centersIris?: number[][]; + centersIris2?: number[][]; }; -const KMeansStepExample:React.FC = ({ - hidden= false, - xLabel = '', - yLabel = '', - k = 2, - trainingData = trainData, - trainingDataIris = trainDataIris, - trainingDataIris2 = trainDataIris2, - centers = [[50, 70], [50, 80]], - centersIris = [[2, 2], [7, 5]], - centersIris2 = [[20, 20], [40, 40]], +const KMeansStepExample: React.FC = ({ + hidden = false, + xLabel = '', + yLabel = '', + k = 2, + trainingData = trainData, + trainingDataIris = trainDataIris, + trainingDataIris2 = trainDataIris2, + centers = [ + [50, 70], + [50, 80], + ], + centersIris = [ + [2, 2], + [7, 5], + ], + centersIris2 = [ + [20, 20], + [40, 40], + ], }) => { - const kmeansData:number[][] = organiseData(trainingData); - const kmeansIrisData:number[][] = organiseData(trainingDataIris); - - const ans2: KMeansResult[] = kmeans(kmeansData, k, { initialization: centers, withIterations: true }, ); - const ans2iris = kmeans(kmeansIrisData, k, { initialization: centersIris, withIterations: true }, ); - - const kmeansIrisData2 = organiseData(trainingDataIris2); - const ans2iris2 = kmeans(kmeansIrisData2, k, { initialization: centersIris2, withIterations: true }, ); - - let gen_out: KMeansResult[] = []; - for (const element of ans2) { - gen_out.push(element); - } - - let gen_outIris:KMeansResult[] = []; - for (const element of ans2iris) { - gen_outIris.push(element); - } - - let gen_outIris2:KMeansResult[] = []; - for (const element of ans2iris2) { - gen_outIris2.push(element); - } - - const [original, setO]: [number, Function] = useState(0); - - const gen = original === 0 ? gen_out : (original === 1 ? gen_outIris : gen_outIris2); - const [r, setR] = useState(0); - const changeO = () => { - setO((original+1) % 3); - setR(0); - return; - } - - if (gen.length === 0) return
; - - let bubData:BubbleDataEntry[] = []; - let data3 = original === 0 ? organiseData(trainData) : (original === 1 ? organiseData(trainDataIris) : organiseData(trainDataIris2)); - let cntrdss = gen[r].centroids; - let c2 = [cntrdss[0].centroid, cntrdss[1].centroid]; - - let labels: number[] = getClasses(data3, c2); - - processdata(bubData, labels, c2, hidden, data3, k); - - // data that will be put into the chart - const data:{datasets: BubbleDataEntry[]} = {datasets: []}; - - Object.entries(bubData).forEach((cluster) => { - data.datasets.push(cluster[1]); - }); - - const options = { - showLines: false, - tooltips: {enabled: false}, - scales: { - yAxes: [{ - scaleLabel: { display: true, labelString: yLabel, fontSize: 16, fontFamily: 'open sans', fontStyle: 'italic bold', fontColor: "#394D73" }, - gridLines: {lineWidth: 3, color: '#8D9DBA'}, - ticks: { - fontColor: '#394D73', - beginAtZero: true, - min: original === 0 ? 0 : (original === 1 ? 1 : 0), - max: original === 0 ? 120 : (original === 1 ? 7 : 40), - } - }], - xAxes: [{ - scaleLabel: { display: true, labelString: xLabel, fontSize: 16, fontFamily: 'open sans', fontStyle: 'italic bold', fontColor: "#394D73" }, - gridLines: {lineWidth: 3, color: '#8D9DBA'}, - ticks: { - fontColor: '#394D73', - beginAtZero: true, - min: original === 0 ? 0 : (original === 1 ? 1 : 0), - max: original === 0 ? 250 : (original === 1 ? 10 : 100), - } - }], + const kmeansData: number[][] = organiseData(trainingData); + const kmeansIrisData: number[][] = organiseData(trainingDataIris); + + const ans2: KMeansResult[] = kmeans(kmeansData, k, { + initialization: centers, + withIterations: true, + }); + const ans2iris = kmeans(kmeansIrisData, k, { + initialization: centersIris, + withIterations: true, + }); + + const kmeansIrisData2 = organiseData(trainingDataIris2); + const ans2iris2 = kmeans(kmeansIrisData2, k, { + initialization: centersIris2, + withIterations: true, + }); + + const genOut: KMeansResult[] = []; + // eslint-disable-next-line + for (const element of ans2) { + genOut.push(element); + } + + const genOutIris: KMeansResult[] = []; + // eslint-disable-next-line + for (const element of ans2iris) { + genOutIris.push(element); + } + + const genOutIris2: KMeansResult[] = []; + + // eslint-disable-next-line + for (const element of ans2iris2) { + genOutIris2.push(element); + } + + const [original, setO]: [number, Function] = useState(0); + + const gen = + // eslint-disable-next-line + original === 0 ? genOut : original === 1 ? genOutIris : genOutIris2; + const [r, setR] = useState(0); + const changeO = () => { + setO((original + 1) % 3); + setR(0); + }; + + if (gen.length === 0) return
; + + const bubData: BubbleDataEntry[] = []; + const data3 = + // eslint-disable-next-line + original === 0 + ? organiseData(trainData) + : original === 1 + ? organiseData(trainDataIris) + : organiseData(trainDataIris2); + const cntrdss = gen[r].centroids; + const c2 = [cntrdss[0].centroid, cntrdss[1].centroid]; + + const labels: number[] = getClasses(data3, c2); + + processdata(bubData, labels, c2, hidden, data3, k); + + // data that will be put into the chart + const data: { datasets: BubbleDataEntry[] } = { datasets: [] }; + + Object.entries(bubData).forEach(cluster => { + data.datasets.push(cluster[1]); + }); + + const options = { + showLines: false, + tooltips: { enabled: false }, + scales: { + yAxes: [ + { + scaleLabel: { + display: true, + labelString: yLabel, + fontSize: 16, + fontFamily: 'open sans', + fontStyle: 'italic bold', + fontColor: '#394D73', + }, + gridLines: { lineWidth: 3, color: '#8D9DBA' }, + ticks: { + fontColor: '#394D73', + beginAtZero: true, + // eslint-disable-next-line + min: original === 0 ? 0 : original === 1 ? 1 : 0, + // eslint-disable-next-line + max: original === 0 ? 120 : original === 1 ? 7 : 40, + }, }, - legend: { - labels: { - fontSize: 14, - fontFamily: 'arial', - fontStyle: 'bold', - fontColor: "#394D73" - } + ], + xAxes: [ + { + scaleLabel: { + display: true, + labelString: xLabel, + fontSize: 16, + fontFamily: 'open sans', + fontStyle: 'italic bold', + fontColor: '#394D73', + }, + gridLines: { lineWidth: 3, color: '#8D9DBA' }, + ticks: { + fontColor: '#394D73', + beginAtZero: true, + // eslint-disable-next-line + min: original === 0 ? 0 : original === 1 ? 1 : 0, + // eslint-disable-next-line + max: original === 0 ? 250 : original === 1 ? 10 : 100, + }, }, - animation: { - duration: 0 - } - }; - - return ( -
- -
-
- -
Step {r}/{gen.length - 1}
- -
-
- -
-
+ ], + }, + legend: { + labels: { + fontSize: 14, + fontFamily: 'arial', + fontStyle: 'bold', + fontColor: '#394D73', + }, + }, + animation: { + duration: 0, + }, + }; + + return ( +
+ +
+
+ +
+ {/* eslint-disable-next-line */} + Step {r} / {gen.length - 1} +
+ +
+
+
- ); -} +
+
+ ); +}; export default KMeansStepExample; diff --git a/src/modules/stateSpaces/kmeans/ml-kmeans.d.ts b/src/modules/stateSpaces/kmeans/ml-kmeans.d.ts index a0b6418..932a163 100644 --- a/src/modules/stateSpaces/kmeans/ml-kmeans.d.ts +++ b/src/modules/stateSpaces/kmeans/ml-kmeans.d.ts @@ -1,3 +1,3 @@ -/** Declaration file generated by dts-gen */ - -declare module 'ml-kmeans'; +/** Declaration file generated by dts-gen */ + +declare module 'ml-kmeans'; diff --git a/src/modules/stateSpaces/kmeans/utils.ts b/src/modules/stateSpaces/kmeans/utils.ts index 416f1e5..e503ce6 100644 --- a/src/modules/stateSpaces/kmeans/utils.ts +++ b/src/modules/stateSpaces/kmeans/utils.ts @@ -3,129 +3,177 @@ import './kmeans.css'; import { squaredEuclidean } from 'ml-distance-euclidean'; // types for each of the four datasets -export type KMeansResult = {clusters: [], centroids: {centroid: number[]}[], converged: [], iterations: number}; -export interface DataFormat { Driver_ID: number, Distance_Feature: number, Speeding_Feature:number}; -export interface DataFormat2 { sepalLength: number, sepalWidth: number, petalLength:number, petalWidth:number, species:string}; -export interface DataFormat3 { petalLength:number, petalWidth:number, species:string }; -export interface TitanicData { - PassengerId: number, - Survived: number, - Pclass: number, - Name: string, - Sex: string, - Age: number, - SibSp: number, - Parch: number, - Ticket: string | number, - Fare: number, - Cabin: string, - Embarked: string +export type KMeansResult = { + clusters: []; + centroids: { centroid: number[] }[]; + converged: []; + iterations: number; }; +export interface DataFormat { + Driver_ID: number; + Distance_Feature: number; + Speeding_Feature: number; +} +export interface DataFormat2 { + sepalLength: number; + sepalWidth: number; + petalLength: number; + petalWidth: number; + species: string; +} +export interface DataFormat3 { + petalLength: number; + petalWidth: number; + species: string; +} +export interface TitanicData { + PassengerId: number; + Survived: number; + Pclass: number; + Name: string; + Sex: string; + Age: number; + SibSp: number; + Parch: number; + Ticket: string | number; + Fare: number; + Cabin: string; + Embarked: string; +} // artificially added points (all datasets are converted into this format with two features) -export interface AddedPoint {Distance_Feature:number, Speeding_Feature:number}; +export interface AddedPoint { + Distance_Feature: number; + Speeding_Feature: number; +} -export type InputData = DataFormat | DataFormat2 | DataFormat3 | TitanicData | AddedPoint; +export type InputData = + | DataFormat + | DataFormat2 + | DataFormat3 + | TitanicData + | AddedPoint; -export type ScatterData = {datasets: ScatterDataData[]}; -export type ScatterDataData = {data:{x:number, y:number, pointRadius:number, backgroundColor:string}[]}; +export type ScatterData = { datasets: ScatterDataData[] }; +export type ScatterDataData = { + data: { + x: number; + y: number; + pointRadius: number; + backgroundColor: string; + }[]; +}; // points to remove -export type PointToRemove = {ds_index: number, ind: number}; +export type PointToRemove = { dsIndex: number; ind: number }; export type PointToRemoveList = [PointToRemove[][], Function]; -export type NewClusterType = {x:number, y:number, r:number}; -export type BubbleDataEntry = {label:string[], backgroundColor:string, borderColor:string, data:NewClusterType[], pointRadius?:number, hidden?: boolean, dragData?: boolean }; +export type NewClusterType = { x: number; y: number; r: number }; +export type BubbleDataEntry = { + label: string[]; + backgroundColor: string; + borderColor: string; + data: NewClusterType[]; + pointRadius?: number; + hidden?: boolean; + dragData?: boolean; +}; export type AddedPointList = [AddedPoint[][], Function]; // kmeans for clusters -export const cluster_colors = ['#99FF99', '#99CCFF']; -export const center_colors = ['#3cb450', "#5360fc"]; -export const centerborder_colors = ['#004E00', '#00007D' ]; +export const clusterColors = ['#99FF99', '#99CCFF']; +export const centerColors = ['#3cb450', '#5360fc']; +export const centerborderColors = ['#004E00', '#00007D']; /* * @param data: array of points * @param centers: two centers * @return array of labels (which its closer to), 0 for first center, 1 for second center */ -export function getClasses(data:number[][], centers: number[][]) { - return data.map(x => squaredEuclidean(x, centers[0]) > squaredEuclidean(x, centers[1]) ? 1 : 0); +export function getClasses(data: number[][], centers: number[][]) { + return data.map(x => + squaredEuclidean(x, centers[0]) > squaredEuclidean(x, centers[1]) ? 1 : 0, + ); } // Data processing export const organiseData = (data: InputData[]) => { - const organisedData: number[][] = []; - for (let i = 0; i < data.length; i++) { - const newRow:number[] = []; - const curRow:InputData = data[i]; - if ((curRow as DataFormat).Distance_Feature) { - const temp:DataFormat = curRow as DataFormat; - newRow.push(temp.Distance_Feature); - newRow.push(temp.Speeding_Feature); - } - else if ((curRow as DataFormat2).sepalLength) { - const temp:DataFormat2 = curRow as DataFormat2; - newRow.push(temp.sepalLength); - newRow.push(temp.sepalWidth); - } - else if((curRow as TitanicData).Age) { - const temp:TitanicData = curRow as TitanicData; - newRow.push(temp.Age); - newRow.push(temp.Fare); - } - else { - const temp:DataFormat3 = curRow as DataFormat3; - newRow.push(temp.petalLength * 10); - newRow.push(temp.petalWidth * 10); - } - organisedData.push(newRow); + const organisedData: number[][] = []; + for (let i = 0; i < data.length; i += 1) { + const newRow: number[] = []; + const curRow: InputData = data[i]; + if ((curRow as DataFormat).Distance_Feature) { + const temp: DataFormat = curRow as DataFormat; + newRow.push(temp.Distance_Feature); + newRow.push(temp.Speeding_Feature); + } else if ((curRow as DataFormat2).sepalLength) { + const temp: DataFormat2 = curRow as DataFormat2; + newRow.push(temp.sepalLength); + newRow.push(temp.sepalWidth); + } else if ((curRow as TitanicData).Age) { + const temp: TitanicData = curRow as TitanicData; + newRow.push(temp.Age); + newRow.push(temp.Fare); + } else { + const temp: DataFormat3 = curRow as DataFormat3; + newRow.push(temp.petalLength * 10); + newRow.push(temp.petalWidth * 10); } - return organisedData; -} + organisedData.push(newRow); + } + return organisedData; +}; // processing for second and third chart -export const processdata = (bdata: BubbleDataEntry[], clsters: number[], cntroids: number[][], hidden: boolean, data3: number[][], k: number) => { - // add centers - for (let c = 0; c < cntroids.length; c++ ){ - const newCluster:NewClusterType[] = []; - newCluster.push({ - x: cntroids[c][0], - y: cntroids[c][1], - r: 3 - }); +export const processdata = ( + bdata: BubbleDataEntry[], + clsters: number[], + cntroids: number[][], + hidden: boolean, + data3: number[][], + k: number, +) => { + // add centers + for (let c = 0; c < cntroids.length; c += 1) { + const newCluster: NewClusterType[] = []; + newCluster.push({ + x: cntroids[c][0], + y: cntroids[c][1], + r: 3, + }); - const colour = center_colors[c]; - const cb = centerborder_colors[c]; - bdata.push({ - label: [`center ${c }`], - backgroundColor: colour, - borderColor: cb, - data: newCluster, - hidden: hidden, - pointRadius: 7, + const colour = centerColors[c]; + const cb = centerborderColors[c]; + bdata.push({ + label: [`center ${c}`], + backgroundColor: colour, + borderColor: cb, + data: newCluster, + hidden, + pointRadius: 7, + }); + } + + // add clusters + for (let ci = 0; ci < k; ci += 1) { + const newCluster: NewClusterType[] = []; + for (let ri = 0; ri < clsters.length; ri += 1) { + if (clsters[ri] === ci) { + newCluster.push({ + x: data3[ri][0], + y: data3[ri][1], + r: 3, }); + } } - // add clusters - for (let ci = 0; ci < k; ci++) { - const newCluster:NewClusterType[] = []; - for (let ri = 0; ri < clsters.length; ri++){ - if (clsters[ri] === ci) { - newCluster.push({ - x: data3[ri][0], - y: data3[ri][1], - r: 3 - }); - } - } - - const colour = cluster_colors[ci]; - bdata.push({ - label: [`cluster ${ci}`], - backgroundColor: colour, - borderColor: colour, - data: newCluster, - // dragData: t - }); - }; -} + const colour = clusterColors[ci]; + bdata.push({ + label: [`cluster ${ci}`], + backgroundColor: colour, + borderColor: colour, + data: newCluster, + // dragData: t + }); + } +}; diff --git a/src/modules/stateSpaces/pca/PCA.tsx b/src/modules/stateSpaces/pca/PCA.tsx index fa7edaa..92ea448 100644 --- a/src/modules/stateSpaces/pca/PCA.tsx +++ b/src/modules/stateSpaces/pca/PCA.tsx @@ -4,134 +4,256 @@ import datasetIris from 'ml-dataset-iris'; import { BasicScatter, DataSeriesMap, ColorMap } from '../common/BasicScatter'; import './PCA.css'; -type PCAProps = {labelColor: string, labelColorHex?: string}; +const COLORS = [ + '#003f5c', + '#ef5675', + '#FFC107', + '#00B0FF', + '#FF3D00', + '#4DB6AC', +]; -/** - * Interactive demo of PCA. - * - * @param labelColor color of the demo's label (as a tailwind class name) - * @param labelColorHex hex color of the demo's label - */ -export const PCADemo = ({labelColor, labelColorHex = ''}: PCAProps) => { +// Moving these outside so they are only calculated once (this will change if we dynamically get datasets) +const dataset: number[][] = datasetIris.getNumbers(); // rows represent the samples and columns the features +const irisClasses: string[] = datasetIris.getClasses(); // the whole column of flower types +const columns = [ + '', + '', + 'Sepal Length', + 'Sepal Width', + 'Petal Length', + 'Petal Width', +]; +const pcaColumns = [ + 'PC1', + 'PC2', + 'Sepal Length', + 'Sepal Width', + 'Petal Length', + 'Petal Width', +]; - return ( -
- - - - -
- ); -} +const prediction = new PCA(dataset).predict(dataset); -export const RawDataTable = () => { - const [showClass, setShowClass] = useState(false); +export const config = { + dataset, + classes: irisClasses, + columns, + pcaColumns, + prediction, +}; +const colorMap: ColorMap = {}; +const dataByClass: { [dataClass: string]: number[][] } = {}; +datasetIris.getDistinctClasses().forEach((dataClass: string, i: number) => { + colorMap[dataClass] = COLORS[i] || '#de425b'; + dataByClass[dataClass] = []; + dataset.forEach((row, idx) => { + if (dataClass === irisClasses[idx]) { + dataByClass[dataClass].push( + [prediction.get(idx, 0), prediction.get(idx, 1)].concat(row), + ); + } + }); +}); +export const RawDataTable = () => { + const [showClass, setShowClass] = useState(false); - return ( + return (
-
- - - - {columns.map(title => title && )} - - - - - {dataset.map((row: number[], idx: number) => { - return ( - - {row.map((val: number, idx: number) => )} - - ); - })} - -
{title} {setShowClass(!showClass)}} - title={showClass ? 'Hide Classes' : 'Display Classes'}> - {showClass ? 'Class' : 'â–º'} -
{val}{showClass && classes[idx]}
-
-
); -} +
+ + + + {columns.map(title => title && )} + + + + + {dataset.map((row: number[], idx: number) => ( + <> + {/* eslint-disable-next-line */} + + {/* eslint-disable-next-line */} + {row.map((val: number, idx: number) => ( + <> + {/* eslint-disable-next-line */} + + + ))} + + + + ))} + +
{title} { + setShowClass(!showClass); + }} + title={showClass ? 'Hide Classes' : 'Display Classes'} + > + {showClass ? 'Class' : 'â–º'} +
{val}{showClass && irisClasses[idx]}
+
+
+ ); +}; +type AxisSelectorType = { + columnSet: string[]; + selected: number; + onChange: (arg: number) => void; +}; +export const AxisSelector: React.FC = ({ + columnSet, + selected, + onChange, +}) => ( +
+ {columnSet.map( + (col, idx) => + col && ( + + ), + )} +
+); // Plot all samples in dataset, choose what 2 features to use as the axes -export const SelectableAxisChart = (props: { columnSet: string[], initXIdx: number, initYIdx: number, labelColor: string, labelColorHex: string }) => { - const [xIdx, setXIdx] = useState(props.initXIdx); - const [yIdx, setYIdx] = useState(props.initYIdx); - const points: DataSeriesMap = {}; - Object.entries(dataByClass).forEach(([dataClass, nums]) => { - points[dataClass] = nums.map(row => ({ x: row[xIdx], y: row[yIdx] })); - }) - - return ( -
-
-

Select Y Axis

- -
-
- -
-
-

Select X Axis

- -
-
); +type SelectableAxisChartType = { + columnSet: string[]; + initXIdx: number; + initYIdx: number; + labelColor: string; + labelColorHex: string; }; +export const SelectableAxisChart: React.FC = ({ + columnSet, + initXIdx, + initYIdx, + labelColor, + labelColorHex, +}) => { + const [xIdx, setXIdx] = useState(initXIdx); + const [yIdx, setYIdx] = useState(initYIdx); + const points: DataSeriesMap = {}; + Object.entries(dataByClass).forEach(([dataClass, nums]) => { + points[dataClass] = nums.map(row => ({ x: row[xIdx], y: row[yIdx] })); + }); -export const StaticAxisChart = (props: { xIdx: number, yIdx: number, columnSet: string[], classes: string[], labelColorHex: string }) => { - - const points: DataSeriesMap = {}; - props.classes.forEach((dataClass) => { - console.log(dataClass); - points[dataClass] = dataByClass[dataClass].map(row => ({ x: row[props.xIdx], y: row[props.yIdx] })); - }); - - return ( -
-
- -
-
); - -} - -export const AxisSelector = (props: { columnSet: string[], selected: number, onChange: (arg: number) => void }) => - (
- {props.columnSet.map((col, idx) => ( - col && - ))} -
); + return ( +
+
+

+ Select Y Axis +

+ +
+
+ +
+
+

+ Select X Axis +

+ +
+
+ ); +}; -const COLORS = ['#003f5c', '#ef5675', '#FFC107', '#00B0FF', '#FF3D00', '#4DB6AC']; +type StaticAxisChartType = { + xIdx: number; + yIdx: number; + columnSet: string[]; + classes: string[]; + labelColorHex: string; +}; +export const StaticAxisChart: React.FC = ({ + xIdx, + yIdx, + columnSet, + classes, + labelColorHex, +}) => { + const points: DataSeriesMap = {}; + classes.forEach(dataClass => { + points[dataClass] = dataByClass[dataClass].map(row => ({ + x: row[xIdx], + y: row[yIdx], + })); + }); -// Moving these outside so they are only calculated once (this will change if we dynamically get datasets) -const dataset: number[][] = datasetIris.getNumbers(); // rows represent the samples and columns the features -const classes: string[] = datasetIris.getClasses(); // the whole column of flower types -const columns = ['', '', 'Sepal Length', 'Sepal Width', 'Petal Length', 'Petal Width']; -const pcaColumns = ['PC1', 'PC2', 'Sepal Length', 'Sepal Width', 'Petal Length', 'Petal Width']; -const prediction = new PCA(dataset).predict(dataset); + return ( +
+
+ +
+
+ ); +}; -export const config = { dataset, classes, columns, pcaColumns, prediction }; +type PCAProps = { labelColor: string; labelColorHex?: string }; -const colorMap: ColorMap = {}; -const dataByClass: { [dataClass: string]: number[][] } = {}; -datasetIris.getDistinctClasses().forEach((dataClass: string, i: number) => { - colorMap[dataClass] = COLORS[i] || '#de425b'; - dataByClass[dataClass] = []; - dataset.forEach((row, idx) => { - if (dataClass === classes[idx]) { - dataByClass[dataClass].push([prediction.get(idx, 0), prediction.get(idx, 1)].concat(row)); - } - }); -}) +/** + * Interactive demo of PCA. + * + * @param labelColor color of the demo's label (as a tailwind class name) + * @param labelColorHex hex color of the demo's label + */ +const PCADemo: React.FC = ({ labelColor, labelColorHex = '' }) => ( +
+ + + + +
+); -export default PCADemo; \ No newline at end of file +export default PCADemo; diff --git a/src/serviceWorker.js b/src/serviceWorker.js index b04b771..f8a7a76 100644 --- a/src/serviceWorker.js +++ b/src/serviceWorker.js @@ -10,14 +10,16 @@ // To learn more about the benefits of this model and instructions on how to // opt-in, read https://bit.ly/CRA-PWA +/* eslint-disable */ + const isLocalhost = Boolean( window.location.hostname === 'localhost' || // [::1] is the IPv6 localhost address. window.location.hostname === '[::1]' || // 127.0.0.0/8 are considered localhost for IPv4. window.location.hostname.match( - /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ - ) + /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/, + ), ); export function register(config) { @@ -43,7 +45,7 @@ export function register(config) { navigator.serviceWorker.ready.then(() => { console.log( 'This web app is being served cache-first by a service ' + - 'worker. To learn more, visit https://bit.ly/CRA-PWA' + 'worker. To learn more, visit https://bit.ly/CRA-PWA', ); }); } else { @@ -71,7 +73,7 @@ function registerValidSW(swUrl, config) { // content until all client tabs are closed. console.log( 'New content is available and will be used when all ' + - 'tabs for this page are closed. See https://bit.ly/CRA-PWA.' + 'tabs for this page are closed. See https://bit.ly/CRA-PWA.', ); // Execute callback @@ -123,7 +125,7 @@ function checkValidServiceWorker(swUrl, config) { }) .catch(() => { console.log( - 'No internet connection found. App is running in offline mode.' + 'No internet connection found. App is running in offline mode.', ); }); } diff --git a/tailwind.config.js b/tailwind.config.js index 10cd395..dd146cd 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -19,57 +19,56 @@ module.exports = { modulePaleBlue: '#CBD9F2', moduleTeal: '#0FD4C0', moduleOffwhite: '#F2F2F2', - moduleNavy: '#394D73' + moduleNavy: '#394D73', }, fontFamily: { - opensans: ["open sans", "sans-serif"], - roboto: ["roboto", "sans-serif"], - robotoMono: ["roboto-mono", "sans-serif"] + opensans: ['open sans', 'sans-serif'], + roboto: ['roboto', 'sans-serif'], + robotoMono: ['roboto-mono', 'sans-serif'], }, fontSize: { - "3.5xl": ['32px'], - "7xl": ['72px'] + '3.5xl': ['32px'], + '7xl': ['72px'], }, fontWeight: { - 'micro': 25 + micro: 25, }, - backgroundImage: theme => ({ - 'about': 'url("../media/aboutPage/aboutCurve.svg")', - 'landing-page': 'url("../media/landingPage/background_landing_page.svg")' + backgroundImage: () => ({ + about: 'url("../media/aboutPage/aboutCurve.svg")', + 'landing-page': + 'url("../media/landingPage/background_landing_page.svg")', }), backgroundSize: { - stretchBottom: '103% 50%' + stretchBottom: '103% 50%', }, borderRadius: { - module: '64px' + module: '64px', }, boxShadow: { module: '12px 10px 19px rgba(0, 0, 0, 0.30)', spacing: { - '500px': '500px' - } - } - , + '500px': '500px', + }, + }, top: { - '-1': '-1px' + '-1': '-1px', }, maxHeight: { xs: '20rem', sm: '24rem', md: '28rem', - lg: '32rem' + lg: '32rem', }, width: { - '35vw': '35vw' - } + '35vw': '35vw', + }, }, variants: { mixBlendMode: ['responsive'], backgroundBlendMode: ['responsive'], isolation: ['responsive'], }, - plugins: [ - require('tailwindcss-blend-mode')() - ], - } -} + /* eslint-disable-next-line */ + plugins: [require('tailwindcss-blend-mode')()], + }, +}; diff --git a/tsconfig.eslint.json b/tsconfig.eslint.json new file mode 100644 index 0000000..b7db04f --- /dev/null +++ b/tsconfig.eslint.json @@ -0,0 +1,5 @@ +{ + "extends": "./tsconfig.json", + "include": ["./*.config.js", "./*.json", "src/**/*.ts", "src/**/*.tsx", "src/**/*.js", "src/**/*.jsx" , "./.eslintrc.js" ], + "exclude": ["node_modules" ] +} diff --git a/yarn.lock b/yarn.lock index 53ad4a4..88dd4bc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9,17 +9,17 @@ dependencies: "@babel/highlight" "^7.10.4" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.11", "@babel/code-frame@^7.5.5": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" - integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.5.5": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.13.tgz#dcfc826beef65e75c50e21d3837d7d95798dd658" + integrity sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g== dependencies: - "@babel/highlight" "^7.10.4" + "@babel/highlight" "^7.12.13" -"@babel/compat-data@^7.12.1", "@babel/compat-data@^7.12.5", "@babel/compat-data@^7.12.7": - version "7.12.7" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.12.7.tgz#9329b4782a7d6bbd7eef57e11addf91ee3ef1e41" - integrity sha512-YaxPMGs/XIWtYqrdEOZOCPsVWfEoriXopnsz3/i7apYPXQ3698UFhS6dVT1KN5qOsWmVgw/FOrmQgpRaZayGsw== +"@babel/compat-data@^7.12.1", "@babel/compat-data@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.12.13.tgz#27e19e0ed3726ccf54067ced4109501765e7e2e8" + integrity sha512-U/hshG5R+SIoW7HVWIdmy1cB7s3ki+r3FpyEZiCgpi4tFgPnX/vynY80ZGSASOIrUM6O7VxOgCZgdt7h97bUGg== "@babel/core@7.12.3": version "7.12.3" @@ -44,18 +44,18 @@ source-map "^0.5.0" "@babel/core@^7.1.0", "@babel/core@^7.12.3", "@babel/core@^7.7.5", "@babel/core@^7.8.4", "@babel/core@^7.9.0": - version "7.12.10" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.10.tgz#b79a2e1b9f70ed3d84bbfb6d8c4ef825f606bccd" - integrity sha512-eTAlQKq65zHfkHZV0sIVODCPGVgoo1HdBlbSLi9CqOzuZanMv2ihzY+4paiKr1mH+XmYESMAmJ/dpZ68eN6d8w== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.12.10" - "@babel/helper-module-transforms" "^7.12.1" - "@babel/helpers" "^7.12.5" - "@babel/parser" "^7.12.10" - "@babel/template" "^7.12.7" - "@babel/traverse" "^7.12.10" - "@babel/types" "^7.12.10" + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.13.tgz#b73a87a3a3e7d142a66248bf6ad88b9ceb093425" + integrity sha512-BQKE9kXkPlXHPeqissfxo0lySWJcYdEP0hdtJOH/iJfDdhOCcgtNCjftCJg3qqauB4h+lz2N6ixM++b9DN1Tcw== + dependencies: + "@babel/code-frame" "^7.12.13" + "@babel/generator" "^7.12.13" + "@babel/helper-module-transforms" "^7.12.13" + "@babel/helpers" "^7.12.13" + "@babel/parser" "^7.12.13" + "@babel/template" "^7.12.13" + "@babel/traverse" "^7.12.13" + "@babel/types" "^7.12.13" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.1" @@ -64,164 +64,155 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.12.1", "@babel/generator@^7.12.10", "@babel/generator@^7.12.11": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.11.tgz#98a7df7b8c358c9a37ab07a24056853016aba3af" - integrity sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA== +"@babel/generator@^7.12.1", "@babel/generator@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.13.tgz#5f6ebe6c85db99886db2d7b044409196f872a503" + integrity sha512-9qQ8Fgo8HaSvHEt6A5+BATP7XktD/AdAnObUeTRz5/e2y3kbrxZgz32qUJJsdmwUvBJzF4AeV21nGTNwv05Mpw== dependencies: - "@babel/types" "^7.12.11" + "@babel/types" "^7.12.13" jsesc "^2.5.1" source-map "^0.5.0" -"@babel/helper-annotate-as-pure@^7.10.4", "@babel/helper-annotate-as-pure@^7.12.10": - version "7.12.10" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.10.tgz#54ab9b000e60a93644ce17b3f37d313aaf1d115d" - integrity sha512-XplmVbC1n+KY6jL8/fgLVXXUauDIB+lD5+GsQEh6F6GBF1dq1qy4DP4yXWzDKcoqXB3X58t61e85Fitoww4JVQ== +"@babel/helper-annotate-as-pure@^7.10.4", "@babel/helper-annotate-as-pure@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz#0f58e86dfc4bb3b1fcd7db806570e177d439b6ab" + integrity sha512-7YXfX5wQ5aYM/BOlbSccHDbuXXFPxeoUmfWtz8le2yTkTZc+BxsiEnENFoi2SlmA8ewDkG2LgIMIVzzn2h8kfw== dependencies: - "@babel/types" "^7.12.10" + "@babel/types" "^7.12.13" -"@babel/helper-builder-binary-assignment-operator-visitor@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.4.tgz#bb0b75f31bf98cbf9ff143c1ae578b87274ae1a3" - integrity sha512-L0zGlFrGWZK4PbT8AszSfLTM5sDU1+Az/En9VrdT8/LmEiJt4zXt+Jve9DCAnQcbqDhCI+29y/L93mrDzddCcg== +"@babel/helper-builder-binary-assignment-operator-visitor@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.12.13.tgz#6bc20361c88b0a74d05137a65cac8d3cbf6f61fc" + integrity sha512-CZOv9tGphhDRlVjVkAgm8Nhklm9RzSmWpX2my+t7Ua/KT616pEzXsQCjinzvkRvHWJ9itO4f296efroX23XCMA== dependencies: - "@babel/helper-explode-assignable-expression" "^7.10.4" - "@babel/types" "^7.10.4" + "@babel/helper-explode-assignable-expression" "^7.12.13" + "@babel/types" "^7.12.13" -"@babel/helper-compilation-targets@^7.12.1", "@babel/helper-compilation-targets@^7.12.5": - version "7.12.5" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.5.tgz#cb470c76198db6a24e9dbc8987275631e5d29831" - integrity sha512-+qH6NrscMolUlzOYngSBMIOQpKUGPPsc61Bu5W10mg84LxZ7cmvnBHzARKbDoFxVvqqAbj6Tg6N7bSrWSPXMyw== +"@babel/helper-compilation-targets@^7.12.1", "@babel/helper-compilation-targets@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.13.tgz#d689cdef88810aa74e15a7a94186f26a3d773c98" + integrity sha512-dXof20y/6wB5HnLOGyLh/gobsMvDNoekcC+8MCV2iaTd5JemhFkPD73QB+tK3iFC9P0xJC73B6MvKkyUfS9cCw== dependencies: - "@babel/compat-data" "^7.12.5" - "@babel/helper-validator-option" "^7.12.1" + "@babel/compat-data" "^7.12.13" + "@babel/helper-validator-option" "^7.12.11" browserslist "^4.14.5" semver "^5.5.0" -"@babel/helper-create-class-features-plugin@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.12.1.tgz#3c45998f431edd4a9214c5f1d3ad1448a6137f6e" - integrity sha512-hkL++rWeta/OVOBTRJc9a5Azh5mt5WgZUGAKMD8JM141YsE08K//bp1unBBieO6rUKkIPyUE0USQ30jAy3Sk1w== +"@babel/helper-create-class-features-plugin@^7.12.1", "@babel/helper-create-class-features-plugin@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.12.13.tgz#0f1707c2eec1a4604f2a22a6fb209854ef2a399a" + integrity sha512-Vs/e9wv7rakKYeywsmEBSRC9KtmE7Px+YBlESekLeJOF0zbGUicGfXSNi3o+tfXSNS48U/7K9mIOOCR79Cl3+Q== dependencies: - "@babel/helper-function-name" "^7.10.4" - "@babel/helper-member-expression-to-functions" "^7.12.1" - "@babel/helper-optimise-call-expression" "^7.10.4" - "@babel/helper-replace-supers" "^7.12.1" - "@babel/helper-split-export-declaration" "^7.10.4" + "@babel/helper-function-name" "^7.12.13" + "@babel/helper-member-expression-to-functions" "^7.12.13" + "@babel/helper-optimise-call-expression" "^7.12.13" + "@babel/helper-replace-supers" "^7.12.13" + "@babel/helper-split-export-declaration" "^7.12.13" -"@babel/helper-create-regexp-features-plugin@^7.12.1": - version "7.12.7" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.7.tgz#2084172e95443fa0a09214ba1bb328f9aea1278f" - integrity sha512-idnutvQPdpbduutvi3JVfEgcVIHooQnhvhx0Nk9isOINOIGYkZea1Pk2JlJRiUnMefrlvr0vkByATBY/mB4vjQ== +"@babel/helper-create-regexp-features-plugin@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.13.tgz#0996d370a92896c612ae41a4215544bd152579c0" + integrity sha512-XC+kiA0J3at6E85dL5UnCYfVOcIZ834QcAY0TIpgUVnz0zDzg+0TtvZTnJ4g9L1dPRGe30Qi03XCIS4tYCLtqw== dependencies: - "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-annotate-as-pure" "^7.12.13" regexpu-core "^4.7.1" -"@babel/helper-define-map@^7.10.4": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.10.5.tgz#b53c10db78a640800152692b13393147acb9bb30" - integrity sha512-fMw4kgFB720aQFXSVaXr79pjjcW5puTCM16+rECJ/plGS+zByelE8l9nCpV1GibxTnFVmUuYG9U8wYfQHdzOEQ== +"@babel/helper-explode-assignable-expression@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.12.13.tgz#0e46990da9e271502f77507efa4c9918d3d8634a" + integrity sha512-5loeRNvMo9mx1dA/d6yNi+YiKziJZFylZnCo1nmFF4qPU4yJ14abhWESuSMQSlQxWdxdOFzxXjk/PpfudTtYyw== dependencies: - "@babel/helper-function-name" "^7.10.4" - "@babel/types" "^7.10.5" - lodash "^4.17.19" + "@babel/types" "^7.12.13" -"@babel/helper-explode-assignable-expression@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.12.1.tgz#8006a466695c4ad86a2a5f2fb15b5f2c31ad5633" - integrity sha512-dmUwH8XmlrUpVqgtZ737tK88v07l840z9j3OEhCLwKTkjlvKpfqXVIZ0wpK3aeOxspwGrf/5AP5qLx4rO3w5rA== +"@babel/helper-function-name@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz#93ad656db3c3c2232559fd7b2c3dbdcbe0eb377a" + integrity sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA== dependencies: - "@babel/types" "^7.12.1" + "@babel/helper-get-function-arity" "^7.12.13" + "@babel/template" "^7.12.13" + "@babel/types" "^7.12.13" -"@babel/helper-function-name@^7.10.4", "@babel/helper-function-name@^7.12.11": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz#1fd7738aee5dcf53c3ecff24f1da9c511ec47b42" - integrity sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA== +"@babel/helper-get-function-arity@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz#bc63451d403a3b3082b97e1d8b3fe5bd4091e583" + integrity sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg== dependencies: - "@babel/helper-get-function-arity" "^7.12.10" - "@babel/template" "^7.12.7" - "@babel/types" "^7.12.11" + "@babel/types" "^7.12.13" -"@babel/helper-get-function-arity@^7.12.10": - version "7.12.10" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz#b158817a3165b5faa2047825dfa61970ddcc16cf" - integrity sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag== +"@babel/helper-hoist-variables@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.12.13.tgz#13aba58b7480b502362316ea02f52cca0e9796cd" + integrity sha512-KSC5XSj5HreRhYQtZ3cnSnQwDzgnbdUDEFsxkN0m6Q3WrCRt72xrnZ8+h+pX7YxM7hr87zIO3a/v5p/H3TrnVw== dependencies: - "@babel/types" "^7.12.10" + "@babel/types" "^7.12.13" -"@babel/helper-hoist-variables@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.4.tgz#d49b001d1d5a68ca5e6604dda01a6297f7c9381e" - integrity sha512-wljroF5PgCk2juF69kanHVs6vrLwIPNp6DLD+Lrl3hoQ3PpPPikaDRNFA+0t81NOoMt2DL6WW/mdU8k4k6ZzuA== - dependencies: - "@babel/types" "^7.10.4" - -"@babel/helper-member-expression-to-functions@^7.12.1", "@babel/helper-member-expression-to-functions@^7.12.7": - version "7.12.7" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz#aa77bd0396ec8114e5e30787efa78599d874a855" - integrity sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw== +"@babel/helper-member-expression-to-functions@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.13.tgz#c5715695b4f8bab32660dbdcdc2341dec7e3df40" + integrity sha512-B+7nN0gIL8FZ8SvMcF+EPyB21KnCcZHQZFczCxbiNGV/O0rsrSBlWGLzmtBJ3GMjSVMIm4lpFhR+VdVBuIsUcQ== dependencies: - "@babel/types" "^7.12.7" + "@babel/types" "^7.12.13" -"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.12.1", "@babel/helper-module-imports@^7.12.5": - version "7.12.5" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz#1bfc0229f794988f76ed0a4d4e90860850b54dfb" - integrity sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA== +"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.12.1", "@babel/helper-module-imports@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.12.13.tgz#ec67e4404f41750463e455cc3203f6a32e93fcb0" + integrity sha512-NGmfvRp9Rqxy0uHSSVP+SRIW1q31a7Ji10cLBcqSDUngGentY4FRiHOFZFE1CLU5eiL0oE8reH7Tg1y99TDM/g== dependencies: - "@babel/types" "^7.12.5" + "@babel/types" "^7.12.13" -"@babel/helper-module-transforms@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz#7954fec71f5b32c48e4b303b437c34453fd7247c" - integrity sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w== +"@babel/helper-module-transforms@^7.12.1", "@babel/helper-module-transforms@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.12.13.tgz#01afb052dcad2044289b7b20beb3fa8bd0265bea" + integrity sha512-acKF7EjqOR67ASIlDTupwkKM1eUisNAjaSduo5Cz+793ikfnpe7p4Q7B7EWU2PCoSTPWsQkR7hRUWEIZPiVLGA== dependencies: - "@babel/helper-module-imports" "^7.12.1" - "@babel/helper-replace-supers" "^7.12.1" - "@babel/helper-simple-access" "^7.12.1" - "@babel/helper-split-export-declaration" "^7.11.0" - "@babel/helper-validator-identifier" "^7.10.4" - "@babel/template" "^7.10.4" - "@babel/traverse" "^7.12.1" - "@babel/types" "^7.12.1" + "@babel/helper-module-imports" "^7.12.13" + "@babel/helper-replace-supers" "^7.12.13" + "@babel/helper-simple-access" "^7.12.13" + "@babel/helper-split-export-declaration" "^7.12.13" + "@babel/helper-validator-identifier" "^7.12.11" + "@babel/template" "^7.12.13" + "@babel/traverse" "^7.12.13" + "@babel/types" "^7.12.13" lodash "^4.17.19" -"@babel/helper-optimise-call-expression@^7.10.4", "@babel/helper-optimise-call-expression@^7.12.10": - version "7.12.10" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz#94ca4e306ee11a7dd6e9f42823e2ac6b49881e2d" - integrity sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ== +"@babel/helper-optimise-call-expression@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz#5c02d171b4c8615b1e7163f888c1c81c30a2aaea" + integrity sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA== dependencies: - "@babel/types" "^7.12.10" + "@babel/types" "^7.12.13" -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz#2f75a831269d4f677de49986dff59927533cf375" - integrity sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg== +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.12.13.tgz#174254d0f2424d8aefb4dd48057511247b0a9eeb" + integrity sha512-C+10MXCXJLiR6IeG9+Wiejt9jmtFpxUc3MQqCmPY8hfCjyUGl9kT+B2okzEZrtykiwrc4dbCPdDoz0A/HQbDaA== -"@babel/helper-remap-async-to-generator@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.12.1.tgz#8c4dbbf916314f6047dc05e6a2217074238347fd" - integrity sha512-9d0KQCRM8clMPcDwo8SevNs+/9a8yWVVmaE80FGJcEP8N1qToREmWEGnBn8BUlJhYRFz6fqxeRL1sl5Ogsed7A== +"@babel/helper-remap-async-to-generator@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.12.13.tgz#170365f4140e2d20e5c88f8ba23c24468c296878" + integrity sha512-Qa6PU9vNcj1NZacZZI1Mvwt+gXDH6CTfgAkSjeRMLE8HxtDK76+YDId6NQR+z7Rgd5arhD2cIbS74r0SxD6PDA== dependencies: - "@babel/helper-annotate-as-pure" "^7.10.4" - "@babel/helper-wrap-function" "^7.10.4" - "@babel/types" "^7.12.1" + "@babel/helper-annotate-as-pure" "^7.12.13" + "@babel/helper-wrap-function" "^7.12.13" + "@babel/types" "^7.12.13" -"@babel/helper-replace-supers@^7.12.1": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz#ea511658fc66c7908f923106dd88e08d1997d60d" - integrity sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA== +"@babel/helper-replace-supers@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.12.13.tgz#00ec4fb6862546bd3d0aff9aac56074277173121" + integrity sha512-pctAOIAMVStI2TMLhozPKbf5yTEXc0OJa0eENheb4w09SrgOWEs+P4nTOZYJQCqs8JlErGLDPDJTiGIp3ygbLg== dependencies: - "@babel/helper-member-expression-to-functions" "^7.12.7" - "@babel/helper-optimise-call-expression" "^7.12.10" - "@babel/traverse" "^7.12.10" - "@babel/types" "^7.12.11" + "@babel/helper-member-expression-to-functions" "^7.12.13" + "@babel/helper-optimise-call-expression" "^7.12.13" + "@babel/traverse" "^7.12.13" + "@babel/types" "^7.12.13" -"@babel/helper-simple-access@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz#32427e5aa61547d38eb1e6eaf5fd1426fdad9136" - integrity sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA== +"@babel/helper-simple-access@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.12.13.tgz#8478bcc5cacf6aa1672b251c1d2dde5ccd61a6c4" + integrity sha512-0ski5dyYIHEfwpWGx5GPWhH35j342JaflmCeQmsPWcrOQDtCN6C1zKAVRFVbK53lPW2c9TsuLLSUDf0tIGJ5hA== dependencies: - "@babel/types" "^7.12.1" + "@babel/types" "^7.12.13" "@babel/helper-skip-transparent-expression-wrappers@^7.12.1": version "7.12.1" @@ -230,14 +221,14 @@ dependencies: "@babel/types" "^7.12.1" -"@babel/helper-split-export-declaration@^7.10.4", "@babel/helper-split-export-declaration@^7.11.0", "@babel/helper-split-export-declaration@^7.12.11": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz#1b4cc424458643c47d37022223da33d76ea4603a" - integrity sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g== +"@babel/helper-split-export-declaration@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz#e9430be00baf3e88b0e13e6f9d4eaf2136372b05" + integrity sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg== dependencies: - "@babel/types" "^7.12.11" + "@babel/types" "^7.12.13" -"@babel/helper-validator-identifier@^7.10.4", "@babel/helper-validator-identifier@^7.12.11": +"@babel/helper-validator-identifier@^7.12.11": version "7.12.11" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed" integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw== @@ -247,49 +238,49 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.12.11.tgz#d66cb8b7a3e7fe4c6962b32020a131ecf0847f4f" integrity sha512-TBFCyj939mFSdeX7U7DDj32WtzYY7fDcalgq8v3fBZMNOJQNn7nOYzMaUCiPxPYfCup69mtIpqlKgMZLvQ8Xhw== -"@babel/helper-wrap-function@^7.10.4": - version "7.12.3" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.12.3.tgz#3332339fc4d1fbbf1c27d7958c27d34708e990d9" - integrity sha512-Cvb8IuJDln3rs6tzjW3Y8UeelAOdnpB8xtQ4sme2MSZ9wOxrbThporC0y/EtE16VAtoyEfLM404Xr1e0OOp+ow== +"@babel/helper-wrap-function@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.12.13.tgz#e3ea8cb3ee0a16911f9c1b50d9e99fe8fe30f9ff" + integrity sha512-t0aZFEmBJ1LojdtJnhOaQEVejnzYhyjWHSsNSNo8vOYRbAJNh6r6GQF7pd36SqG7OKGbn+AewVQ/0IfYfIuGdw== dependencies: - "@babel/helper-function-name" "^7.10.4" - "@babel/template" "^7.10.4" - "@babel/traverse" "^7.10.4" - "@babel/types" "^7.10.4" + "@babel/helper-function-name" "^7.12.13" + "@babel/template" "^7.12.13" + "@babel/traverse" "^7.12.13" + "@babel/types" "^7.12.13" -"@babel/helpers@^7.12.1", "@babel/helpers@^7.12.5": - version "7.12.5" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.12.5.tgz#1a1ba4a768d9b58310eda516c449913fe647116e" - integrity sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA== +"@babel/helpers@^7.12.1", "@babel/helpers@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.12.13.tgz#3c75e993632e4dadc0274eae219c73eb7645ba47" + integrity sha512-oohVzLRZ3GQEk4Cjhfs9YkJA4TdIDTObdBEZGrd6F/T0GPSnuV6l22eMcxlvcvzVIPH3VTtxbseudM1zIE+rPQ== dependencies: - "@babel/template" "^7.10.4" - "@babel/traverse" "^7.12.5" - "@babel/types" "^7.12.5" + "@babel/template" "^7.12.13" + "@babel/traverse" "^7.12.13" + "@babel/types" "^7.12.13" -"@babel/highlight@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.4.tgz#7d1bdfd65753538fabe6c38596cdb76d9ac60143" - integrity sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA== +"@babel/highlight@^7.10.4", "@babel/highlight@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.12.13.tgz#8ab538393e00370b26271b01fa08f7f27f2e795c" + integrity sha512-kocDQvIbgMKlWxXe9fof3TQ+gkIPOUSEYhJjqUjvKMez3krV7vbzYCDq39Oj11UAVK7JqPVGQPlgE85dPNlQww== dependencies: - "@babel/helper-validator-identifier" "^7.10.4" + "@babel/helper-validator-identifier" "^7.12.11" chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.12.10", "@babel/parser@^7.12.11", "@babel/parser@^7.12.3", "@babel/parser@^7.12.7", "@babel/parser@^7.7.0": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.11.tgz#9ce3595bcd74bc5c466905e86c535b8b25011e79" - integrity sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg== +"@babel/parser@^7.1.0", "@babel/parser@^7.12.13", "@babel/parser@^7.12.3", "@babel/parser@^7.7.0": + version "7.12.14" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.14.tgz#4adb7c5eef1d437ef965ad1569cd826db8c11dc9" + integrity sha512-xcfxDq3OrBnDsA/Z8eK5/2iPcLD8qbOaSSfOw4RA6jp4i7e6dEQ7+wTwxItEwzcXPQcsry5nZk96gmVPKletjQ== -"@babel/plugin-proposal-async-generator-functions@^7.12.1": - version "7.12.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.12.12.tgz#04b8f24fd4532008ab4e79f788468fd5a8476566" - integrity sha512-nrz9y0a4xmUrRq51bYkWJIO5SBZyG2ys2qinHsN0zHDHVsUaModrkpyWWWXfGqYQmOL3x9sQIcTNN/pBGpo09A== +"@babel/plugin-proposal-async-generator-functions@^7.12.1", "@babel/plugin-proposal-async-generator-functions@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.12.13.tgz#d1c6d841802ffb88c64a2413e311f7345b9e66b5" + integrity sha512-1KH46Hx4WqP77f978+5Ye/VUbuwQld2hph70yaw2hXS2v7ER2f3nlpNMu909HO2rbvP0NKLlMVDPh9KXklVMhA== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-remap-async-to-generator" "^7.12.1" + "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-remap-async-to-generator" "^7.12.13" "@babel/plugin-syntax-async-generators" "^7.8.0" -"@babel/plugin-proposal-class-properties@7.12.1", "@babel/plugin-proposal-class-properties@^7.12.1": +"@babel/plugin-proposal-class-properties@7.12.1": version "7.12.1" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.12.1.tgz#a082ff541f2a29a4821065b8add9346c0c16e5de" integrity sha512-cKp3dlQsFsEs5CWKnN7BnSHOd0EOW8EKpEjkoz1pO2E5KzIDNV9Ros1b0CnmbVgAGXJubOYVBOGCT1OmJwOI7w== @@ -297,6 +288,14 @@ "@babel/helper-create-class-features-plugin" "^7.12.1" "@babel/helper-plugin-utils" "^7.10.4" +"@babel/plugin-proposal-class-properties@^7.12.1", "@babel/plugin-proposal-class-properties@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.12.13.tgz#3d2ce350367058033c93c098e348161d6dc0d8c8" + integrity sha512-8SCJ0Ddrpwv4T7Gwb33EmW1V9PY5lggTO+A8WjyIwxrSHDUyBw4MtF96ifn1n8H806YlxbVCoKXbbmzD6RD+cA== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.12.13" + "@babel/helper-plugin-utils" "^7.12.13" + "@babel/plugin-proposal-decorators@7.12.1": version "7.12.1" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.12.1.tgz#59271439fed4145456c41067450543aee332d15f" @@ -314,31 +313,31 @@ "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-dynamic-import" "^7.8.0" -"@babel/plugin-proposal-export-namespace-from@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.1.tgz#8b9b8f376b2d88f5dd774e4d24a5cc2e3679b6d4" - integrity sha512-6CThGf0irEkzujYS5LQcjBx8j/4aQGiVv7J9+2f7pGfxqyKh3WnmVJYW3hdrQjyksErMGBPQrCnHfOtna+WLbw== +"@babel/plugin-proposal-export-namespace-from@^7.12.1", "@babel/plugin-proposal-export-namespace-from@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.13.tgz#393be47a4acd03fa2af6e3cde9b06e33de1b446d" + integrity sha512-INAgtFo4OnLN3Y/j0VwAgw3HDXcDtX+C/erMvWzuV9v71r7urb6iyMXu7eM9IgLr1ElLlOkaHjJ0SbCmdOQ3Iw== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" -"@babel/plugin-proposal-json-strings@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.12.1.tgz#d45423b517714eedd5621a9dfdc03fa9f4eb241c" - integrity sha512-GoLDUi6U9ZLzlSda2Df++VSqDJg3CG+dR0+iWsv6XRw1rEq+zwt4DirM9yrxW6XWaTpmai1cWJLMfM8qQJf+yw== +"@babel/plugin-proposal-json-strings@^7.12.1", "@babel/plugin-proposal-json-strings@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.12.13.tgz#ced7888a2db92a3d520a2e35eb421fdb7fcc9b5d" + integrity sha512-v9eEi4GiORDg8x+Dmi5r8ibOe0VXoKDeNPYcTTxdGN4eOWikrJfDJCJrr1l5gKGvsNyGJbrfMftC2dTL6oz7pg== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-syntax-json-strings" "^7.8.0" -"@babel/plugin-proposal-logical-assignment-operators@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.12.1.tgz#f2c490d36e1b3c9659241034a5d2cd50263a2751" - integrity sha512-k8ZmVv0JU+4gcUGeCDZOGd0lCIamU/sMtIiX3UWnUc5yzgq6YUGyEolNYD+MLYKfSzgECPcqetVcJP9Afe/aCA== +"@babel/plugin-proposal-logical-assignment-operators@^7.12.1", "@babel/plugin-proposal-logical-assignment-operators@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.12.13.tgz#575b5d9a08d8299eeb4db6430da6e16e5cf14350" + integrity sha512-fqmiD3Lz7jVdK6kabeSr1PZlWSUVqSitmHEe3Z00dtGTKieWnX9beafvavc32kjORa5Bai4QNHgFDwWJP+WtSQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" -"@babel/plugin-proposal-nullish-coalescing-operator@7.12.1", "@babel/plugin-proposal-nullish-coalescing-operator@^7.12.1": +"@babel/plugin-proposal-nullish-coalescing-operator@7.12.1": version "7.12.1" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.12.1.tgz#3ed4fff31c015e7f3f1467f190dbe545cd7b046c" integrity sha512-nZY0ESiaQDI1y96+jk6VxMOaL4LPo/QDHBqL+SF3/vl6dHkTwHlOI8L4ZwuRBHgakRBw5zsVylel7QPbbGuYgg== @@ -346,6 +345,14 @@ "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" +"@babel/plugin-proposal-nullish-coalescing-operator@^7.12.1", "@babel/plugin-proposal-nullish-coalescing-operator@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.12.13.tgz#24867307285cee4e1031170efd8a7ac807deefde" + integrity sha512-Qoxpy+OxhDBI5kRqliJFAl4uWXk3Bn24WeFstPH0iLymFehSAUR8MHpqU7njyXv/qbo7oN6yTy5bfCmXdKpo1Q== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" + "@babel/plugin-proposal-numeric-separator@7.12.1": version "7.12.1" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.1.tgz#0e2c6774c4ce48be412119b4d693ac777f7685a6" @@ -354,29 +361,29 @@ "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-numeric-separator" "^7.10.4" -"@babel/plugin-proposal-numeric-separator@^7.12.1", "@babel/plugin-proposal-numeric-separator@^7.12.7": - version "7.12.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.7.tgz#8bf253de8139099fea193b297d23a9d406ef056b" - integrity sha512-8c+uy0qmnRTeukiGsjLGy6uVs/TFjJchGXUeBqlG4VWYOdJWkhhVPdQ3uHwbmalfJwv2JsV0qffXP4asRfL2SQ== +"@babel/plugin-proposal-numeric-separator@^7.12.1", "@babel/plugin-proposal-numeric-separator@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.13.tgz#bd9da3188e787b5120b4f9d465a8261ce67ed1db" + integrity sha512-O1jFia9R8BUCl3ZGB7eitaAPu62TXJRHn7rh+ojNERCFyqRwJMTmhz+tJ+k0CwI6CLjX/ee4qW74FSqlq9I35w== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-syntax-numeric-separator" "^7.10.4" -"@babel/plugin-proposal-object-rest-spread@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.1.tgz#def9bd03cea0f9b72283dac0ec22d289c7691069" - integrity sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA== +"@babel/plugin-proposal-object-rest-spread@^7.12.1", "@babel/plugin-proposal-object-rest-spread@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.13.tgz#f93f3116381ff94bc676fdcb29d71045cd1ec011" + integrity sha512-WvA1okB/0OS/N3Ldb3sziSrXg6sRphsBgqiccfcQq7woEn5wQLNX82Oc4PlaFcdwcWHuQXAtb8ftbS8Fbsg/sg== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-syntax-object-rest-spread" "^7.8.0" - "@babel/plugin-transform-parameters" "^7.12.1" + "@babel/plugin-transform-parameters" "^7.12.13" -"@babel/plugin-proposal-optional-catch-binding@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.12.1.tgz#ccc2421af64d3aae50b558a71cede929a5ab2942" - integrity sha512-hFvIjgprh9mMw5v42sJWLI1lzU5L2sznP805zeT6rySVRA0Y18StRhDqhSxlap0oVgItRsB6WSROp4YnJTJz0g== +"@babel/plugin-proposal-optional-catch-binding@^7.12.1", "@babel/plugin-proposal-optional-catch-binding@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.12.13.tgz#4640520afe57728af14b4d1574ba844f263bcae5" + integrity sha512-9+MIm6msl9sHWg58NvqpNpLtuFbmpFYk37x8kgnGzAHvX35E1FyAwSUt5hIkSoWJFSAH+iwU8bJ4fcD1zKXOzg== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" "@babel/plugin-proposal-optional-chaining@7.12.1": @@ -388,30 +395,30 @@ "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" "@babel/plugin-syntax-optional-chaining" "^7.8.0" -"@babel/plugin-proposal-optional-chaining@^7.12.1", "@babel/plugin-proposal-optional-chaining@^7.12.7": - version "7.12.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.7.tgz#e02f0ea1b5dc59d401ec16fb824679f683d3303c" - integrity sha512-4ovylXZ0PWmwoOvhU2vhnzVNnm88/Sm9nx7V8BPgMvAzn5zDou3/Awy0EjglyubVHasJj+XCEkr/r1X3P5elCA== +"@babel/plugin-proposal-optional-chaining@^7.12.1", "@babel/plugin-proposal-optional-chaining@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.13.tgz#63a7d805bc8ce626f3234ee5421a2a7fb23f66d9" + integrity sha512-0ZwjGfTcnZqyV3y9DSD1Yk3ebp+sIUpT2YDqP8hovzaNZnQq2Kd7PEqa6iOIUDBXBt7Jl3P7YAcEIL5Pz8u09Q== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" "@babel/plugin-syntax-optional-chaining" "^7.8.0" -"@babel/plugin-proposal-private-methods@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.12.1.tgz#86814f6e7a21374c980c10d38b4493e703f4a389" - integrity sha512-mwZ1phvH7/NHK6Kf8LP7MYDogGV+DKB1mryFOEwx5EBNQrosvIczzZFTUmWaeujd5xT6G1ELYWUz3CutMhjE1w== +"@babel/plugin-proposal-private-methods@^7.12.1", "@babel/plugin-proposal-private-methods@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.12.13.tgz#ea78a12554d784ecf7fc55950b752d469d9c4a71" + integrity sha512-sV0V57uUwpauixvR7s2o75LmwJI6JECwm5oPUY5beZB1nBl2i37hc7CJGqB5G+58fur5Y6ugvl3LRONk5x34rg== dependencies: - "@babel/helper-create-class-features-plugin" "^7.12.1" - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-create-class-features-plugin" "^7.12.13" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-proposal-unicode-property-regex@^7.12.1", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.1.tgz#2a183958d417765b9eae334f47758e5d6a82e072" - integrity sha512-MYq+l+PvHuw/rKUz1at/vb6nCnQ2gmJBNaM62z0OgH7B2W1D9pvkpYtlti9bGtizNIU1K3zm4bZF9F91efVY0w== +"@babel/plugin-proposal-unicode-property-regex@^7.12.1", "@babel/plugin-proposal-unicode-property-regex@^7.12.13", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.13.tgz#bebde51339be829c17aaaaced18641deb62b39ba" + integrity sha512-XyJmZidNfofEkqFV5VC/bLabGmO5QzenPO/YOfGuEbgU+2sSwMmio3YLb4WtBgcmmdwZHyVyv8on77IUjQ5Gvg== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.12.1" - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-create-regexp-features-plugin" "^7.12.13" + "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-syntax-async-generators@^7.8.0", "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" @@ -427,19 +434,19 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-class-properties@^7.12.1", "@babel/plugin-syntax-class-properties@^7.8.3": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.1.tgz#bcb297c5366e79bebadef509549cd93b04f19978" - integrity sha512-U40A76x5gTwmESz+qiqssqmeEsKvcSyvtgktrm0uzcARAmM9I1jR221f6Oq+GmHrcD+LvZDag1UTOTe2fL3TeA== +"@babel/plugin-syntax-class-properties@^7.12.1", "@babel/plugin-syntax-class-properties@^7.12.13", "@babel/plugin-syntax-class-properties@^7.8.3": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" + integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-syntax-decorators@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.12.1.tgz#81a8b535b284476c41be6de06853a8802b98c5dd" - integrity sha512-ir9YW5daRrTYiy9UJ2TzdNIJEZu8KclVzDcfSt4iEmOtwQ4llPtWInNKJyKnVXp1vE4bbVd5S31M/im3mYMO1w== + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.12.13.tgz#fac829bf3c7ef4a1bc916257b403e58c6bdaf648" + integrity sha512-Rw6aIXGuqDLr6/LoBBYE57nKOzQpz/aDkKlMqEwH+Vp0MXbG6H/TfRjaY343LKxzAKAMXIHsQ8JzaZKuDZ9MwA== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-syntax-dynamic-import@^7.8.0": version "7.8.3" @@ -456,11 +463,11 @@ "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-syntax-flow@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.12.1.tgz#a77670d9abe6d63e8acadf4c31bb1eb5a506bbdd" - integrity sha512-1lBLLmtxrwpm4VKmtVFselI/P3pX+G63fAtUUt6b2Nzgao77KNDwyuRt90Mj2/9pKobtt68FdvjfqohZjg/FCA== + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.12.13.tgz#5df9962503c0a9c918381c929d51d4d6949e7e86" + integrity sha512-J/RYxnlSLXZLVR7wTRsozxKT8qbsx1mNKJzXEEjQ0Kjx1ZACcyHgbanNWNCFtc36IzuWhYWPpvJFFoexoOWFmA== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-syntax-import-meta@^7.8.3": version "7.10.4" @@ -476,12 +483,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-jsx@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.1.tgz#9d9d357cc818aa7ae7935917c1257f67677a0926" - integrity sha512-1yRi7yAtB0ETgxdY9ti/p2TivUxJkTdhu/ZbF9MshVGqOx1TdB3b7xCXs49Fupgg50N45KcAsRP/ZqWjs9SRjg== +"@babel/plugin-syntax-jsx@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.13.tgz#044fb81ebad6698fe62c478875575bcbb9b70f15" + integrity sha512-d4HM23Q1K7oq/SLNmG6mRt85l2csmQ0cHRaxRXjKW0YFdEXqlZ5kzFQKH5Uc3rDJECgu+yCRgPkG04Mm98R/1g== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-syntax-logical-assignment-operators@^7.10.4", "@babel/plugin-syntax-logical-assignment-operators@^7.8.3": version "7.10.4" @@ -525,100 +532,99 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-top-level-await@^7.12.1", "@babel/plugin-syntax-top-level-await@^7.8.3": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.1.tgz#dd6c0b357ac1bb142d98537450a319625d13d2a0" - integrity sha512-i7ooMZFS+a/Om0crxZodrTzNEPJHZrlMVGMTEpFAj6rYY/bKCddB0Dk/YxfPuYXOopuhKk/e1jV6h+WUU9XN3A== +"@babel/plugin-syntax-top-level-await@^7.12.1", "@babel/plugin-syntax-top-level-await@^7.12.13", "@babel/plugin-syntax-top-level-await@^7.8.3": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.13.tgz#c5f0fa6e249f5b739727f923540cf7a806130178" + integrity sha512-A81F9pDwyS7yM//KwbCSDqy3Uj4NMIurtplxphWxoYtNPov7cJsDkAFNNyVlIZ3jwGycVsurZ+LtOA8gZ376iQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-syntax-typescript@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.12.1.tgz#460ba9d77077653803c3dd2e673f76d66b4029e5" - integrity sha512-UZNEcCY+4Dp9yYRCAHrHDU+9ZXLYaY9MgBXSRLkB9WjYFRR6quJBumfVrEkUxrePPBwFcpWfNKXqVRQQtm7mMA== +"@babel/plugin-syntax-typescript@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.12.13.tgz#9dff111ca64154cef0f4dc52cf843d9f12ce4474" + integrity sha512-cHP3u1JiUiG2LFDKbXnwVad81GvfyIOmCD6HIEId6ojrY0Drfy2q1jw7BwN7dE84+kTnBjLkXoL3IEy/3JPu2w== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-arrow-functions@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.12.1.tgz#8083ffc86ac8e777fbe24b5967c4b2521f3cb2b3" - integrity sha512-5QB50qyN44fzzz4/qxDPQMBCTHgxg3n0xRBLJUmBlLoU/sFvxVWGZF/ZUfMVDQuJUKXaBhbupxIzIfZ6Fwk/0A== +"@babel/plugin-transform-arrow-functions@^7.12.1", "@babel/plugin-transform-arrow-functions@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.12.13.tgz#eda5670b282952100c229f8a3bd49e0f6a72e9fe" + integrity sha512-tBtuN6qtCTd+iHzVZVOMNp+L04iIJBpqkdY42tWbmjIT5wvR2kx7gxMBsyhQtFzHwBbyGi9h8J8r9HgnOpQHxg== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-async-to-generator@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.12.1.tgz#3849a49cc2a22e9743cbd6b52926d30337229af1" - integrity sha512-SDtqoEcarK1DFlRJ1hHRY5HvJUj5kX4qmtpMAm2QnhOlyuMC4TMdCRgW6WXpv93rZeYNeLP22y8Aq2dbcDRM1A== +"@babel/plugin-transform-async-to-generator@^7.12.1", "@babel/plugin-transform-async-to-generator@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.12.13.tgz#fed8c69eebf187a535bfa4ee97a614009b24f7ae" + integrity sha512-psM9QHcHaDr+HZpRuJcE1PXESuGWSCcbiGFFhhwfzdbTxaGDVzuVtdNYliAwcRo3GFg0Bc8MmI+AvIGYIJG04A== dependencies: - "@babel/helper-module-imports" "^7.12.1" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-remap-async-to-generator" "^7.12.1" + "@babel/helper-module-imports" "^7.12.13" + "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-remap-async-to-generator" "^7.12.13" -"@babel/plugin-transform-block-scoped-functions@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.1.tgz#f2a1a365bde2b7112e0a6ded9067fdd7c07905d9" - integrity sha512-5OpxfuYnSgPalRpo8EWGPzIYf0lHBWORCkj5M0oLBwHdlux9Ri36QqGW3/LR13RSVOAoUUMzoPI/jpE4ABcHoA== +"@babel/plugin-transform-block-scoped-functions@^7.12.1", "@babel/plugin-transform-block-scoped-functions@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.13.tgz#a9bf1836f2a39b4eb6cf09967739de29ea4bf4c4" + integrity sha512-zNyFqbc3kI/fVpqwfqkg6RvBgFpC4J18aKKMmv7KdQ/1GgREapSJAykLMVNwfRGO3BtHj3YQZl8kxCXPcVMVeg== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-block-scoping@^7.12.1", "@babel/plugin-transform-block-scoping@^7.12.11": - version "7.12.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.12.tgz#d93a567a152c22aea3b1929bb118d1d0a175cdca" - integrity sha512-VOEPQ/ExOVqbukuP7BYJtI5ZxxsmegTwzZ04j1aF0dkSypGo9XpDHuOrABsJu+ie+penpSJheDJ11x1BEZNiyQ== +"@babel/plugin-transform-block-scoping@^7.12.1", "@babel/plugin-transform-block-scoping@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.13.tgz#f36e55076d06f41dfd78557ea039c1b581642e61" + integrity sha512-Pxwe0iqWJX4fOOM2kEZeUuAxHMWb9nK+9oh5d11bsLoB0xMg+mkDpt0eYuDZB7ETrY9bbcVlKUGTOGWy7BHsMQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-classes@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.12.1.tgz#65e650fcaddd3d88ddce67c0f834a3d436a32db6" - integrity sha512-/74xkA7bVdzQTBeSUhLLJgYIcxw/dpEpCdRDiHgPJ3Mv6uC11UhjpOhl72CgqbBCmt1qtssCyB2xnJm1+PFjog== +"@babel/plugin-transform-classes@^7.12.1", "@babel/plugin-transform-classes@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.12.13.tgz#9728edc1838b5d62fc93ad830bd523b1fcb0e1f6" + integrity sha512-cqZlMlhCC1rVnxE5ZGMtIb896ijL90xppMiuWXcwcOAuFczynpd3KYemb91XFFPi3wJSe/OcrX9lXoowatkkxA== dependencies: - "@babel/helper-annotate-as-pure" "^7.10.4" - "@babel/helper-define-map" "^7.10.4" - "@babel/helper-function-name" "^7.10.4" - "@babel/helper-optimise-call-expression" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-replace-supers" "^7.12.1" - "@babel/helper-split-export-declaration" "^7.10.4" + "@babel/helper-annotate-as-pure" "^7.12.13" + "@babel/helper-function-name" "^7.12.13" + "@babel/helper-optimise-call-expression" "^7.12.13" + "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-replace-supers" "^7.12.13" + "@babel/helper-split-export-declaration" "^7.12.13" globals "^11.1.0" -"@babel/plugin-transform-computed-properties@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.12.1.tgz#d68cf6c9b7f838a8a4144badbe97541ea0904852" - integrity sha512-vVUOYpPWB7BkgUWPo4C44mUQHpTZXakEqFjbv8rQMg7TC6S6ZhGZ3otQcRH6u7+adSlE5i0sp63eMC/XGffrzg== +"@babel/plugin-transform-computed-properties@^7.12.1", "@babel/plugin-transform-computed-properties@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.12.13.tgz#6a210647a3d67f21f699cfd2a01333803b27339d" + integrity sha512-dDfuROUPGK1mTtLKyDPUavmj2b6kFu82SmgpztBFEO974KMjJT+Ytj3/oWsTUMBmgPcp9J5Pc1SlcAYRpJ2hRA== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-destructuring@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.12.1.tgz#b9a570fe0d0a8d460116413cb4f97e8e08b2f847" - integrity sha512-fRMYFKuzi/rSiYb2uRLiUENJOKq4Gnl+6qOv5f8z0TZXg3llUwUhsNNwrwaT/6dUhJTzNpBr+CUvEWBtfNY1cw== +"@babel/plugin-transform-destructuring@^7.12.1", "@babel/plugin-transform-destructuring@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.12.13.tgz#fc56c5176940c5b41735c677124d1d20cecc9aeb" + integrity sha512-Dn83KykIFzjhA3FDPA1z4N+yfF3btDGhjnJwxIj0T43tP0flCujnU8fKgEkf0C1biIpSv9NZegPBQ1J6jYkwvQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-dotall-regex@^7.12.1", "@babel/plugin-transform-dotall-regex@^7.4.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.1.tgz#a1d16c14862817b6409c0a678d6f9373ca9cd975" - integrity sha512-B2pXeRKoLszfEW7J4Hg9LoFaWEbr/kzo3teWHmtFCszjRNa/b40f9mfeqZsIDLLt/FjwQ6pz/Gdlwy85xNckBA== +"@babel/plugin-transform-dotall-regex@^7.12.1", "@babel/plugin-transform-dotall-regex@^7.12.13", "@babel/plugin-transform-dotall-regex@^7.4.4": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.13.tgz#3f1601cc29905bfcb67f53910f197aeafebb25ad" + integrity sha512-foDrozE65ZFdUC2OfgeOCrEPTxdB3yjqxpXh8CH+ipd9CHd4s/iq81kcUpyH8ACGNEPdFqbtzfgzbT/ZGlbDeQ== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.12.1" - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-create-regexp-features-plugin" "^7.12.13" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-duplicate-keys@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.1.tgz#745661baba295ac06e686822797a69fbaa2ca228" - integrity sha512-iRght0T0HztAb/CazveUpUQrZY+aGKKaWXMJ4uf9YJtqxSUe09j3wteztCUDRHs+SRAL7yMuFqUsLoAKKzgXjw== +"@babel/plugin-transform-duplicate-keys@^7.12.1", "@babel/plugin-transform-duplicate-keys@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.13.tgz#6f06b87a8b803fd928e54b81c258f0a0033904de" + integrity sha512-NfADJiiHdhLBW3pulJlJI2NB0t4cci4WTZ8FtdIuNc2+8pslXdPtRRAEWqUY+m9kNOk2eRYbTAOipAxlrOcwwQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-exponentiation-operator@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.1.tgz#b0f2ed356ba1be1428ecaf128ff8a24f02830ae0" - integrity sha512-7tqwy2bv48q+c1EHbXK0Zx3KXd2RVQp6OC7PbwFNt/dPTAV3Lu5sWtWuAj8owr5wqtWnqHfl2/mJlUmqkChKug== +"@babel/plugin-transform-exponentiation-operator@^7.12.1", "@babel/plugin-transform-exponentiation-operator@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.13.tgz#4d52390b9a273e651e4aba6aee49ef40e80cd0a1" + integrity sha512-fbUelkM1apvqez/yYx1/oICVnGo2KM5s63mhGylrmXUxK/IAXSIf87QIxVfZldWf4QsOafY6vV3bX8aMHSvNrA== dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.12.13" + "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-flow-strip-types@7.12.1": version "7.12.1" @@ -628,124 +634,131 @@ "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-flow" "^7.12.1" -"@babel/plugin-transform-for-of@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.12.1.tgz#07640f28867ed16f9511c99c888291f560921cfa" - integrity sha512-Zaeq10naAsuHo7heQvyV0ptj4dlZJwZgNAtBYBnu5nNKJoW62m0zKcIEyVECrUKErkUkg6ajMy4ZfnVZciSBhg== +"@babel/plugin-transform-for-of@^7.12.1", "@babel/plugin-transform-for-of@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.12.13.tgz#561ff6d74d9e1c8879cb12dbaf4a14cd29d15cf6" + integrity sha512-xCbdgSzXYmHGyVX3+BsQjcd4hv4vA/FDy7Kc8eOpzKmBBPEOTurt0w5fCRQaGl+GSBORKgJdstQ1rHl4jbNseQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-function-name@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.1.tgz#2ec76258c70fe08c6d7da154003a480620eba667" - integrity sha512-JF3UgJUILoFrFMEnOJLJkRHSk6LUSXLmEFsA23aR2O5CSLUxbeUX1IZ1YQ7Sn0aXb601Ncwjx73a+FVqgcljVw== +"@babel/plugin-transform-function-name@^7.12.1", "@babel/plugin-transform-function-name@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.13.tgz#bb024452f9aaed861d374c8e7a24252ce3a50051" + integrity sha512-6K7gZycG0cmIwwF7uMK/ZqeCikCGVBdyP2J5SKNCXO5EOHcqi+z7Jwf8AmyDNcBgxET8DrEtCt/mPKPyAzXyqQ== dependencies: - "@babel/helper-function-name" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-function-name" "^7.12.13" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-literals@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.1.tgz#d73b803a26b37017ddf9d3bb8f4dc58bfb806f57" - integrity sha512-+PxVGA+2Ag6uGgL0A5f+9rklOnnMccwEBzwYFL3EUaKuiyVnUipyXncFcfjSkbimLrODoqki1U9XxZzTvfN7IQ== +"@babel/plugin-transform-literals@^7.12.1", "@babel/plugin-transform-literals@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.13.tgz#2ca45bafe4a820197cf315794a4d26560fe4bdb9" + integrity sha512-FW+WPjSR7hiUxMcKqyNjP05tQ2kmBCdpEpZHY1ARm96tGQCCBvXKnpjILtDplUnJ/eHZ0lALLM+d2lMFSpYJrQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-member-expression-literals@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.1.tgz#496038602daf1514a64d43d8e17cbb2755e0c3ad" - integrity sha512-1sxePl6z9ad0gFMB9KqmYofk34flq62aqMt9NqliS/7hPEpURUCMbyHXrMPlo282iY7nAvUB1aQd5mg79UD9Jg== +"@babel/plugin-transform-member-expression-literals@^7.12.1", "@babel/plugin-transform-member-expression-literals@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.13.tgz#5ffa66cd59b9e191314c9f1f803b938e8c081e40" + integrity sha512-kxLkOsg8yir4YeEPHLuO2tXP9R/gTjpuTOjshqSpELUN3ZAg2jfDnKUvzzJxObun38sw3wm4Uu69sX/zA7iRvg== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-modules-amd@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.12.1.tgz#3154300b026185666eebb0c0ed7f8415fefcf6f9" - integrity sha512-tDW8hMkzad5oDtzsB70HIQQRBiTKrhfgwC/KkJeGsaNFTdWhKNt/BiE8c5yj19XiGyrxpbkOfH87qkNg1YGlOQ== +"@babel/plugin-transform-modules-amd@^7.12.1", "@babel/plugin-transform-modules-amd@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.12.13.tgz#43db16249b274ee2e551e2422090aa1c47692d56" + integrity sha512-JHLOU0o81m5UqG0Ulz/fPC68/v+UTuGTWaZBUwpEk1fYQ1D9LfKV6MPn4ttJKqRo5Lm460fkzjLTL4EHvCprvA== dependencies: - "@babel/helper-module-transforms" "^7.12.1" - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-module-transforms" "^7.12.13" + "@babel/helper-plugin-utils" "^7.12.13" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-commonjs@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.12.1.tgz#fa403124542636c786cf9b460a0ffbb48a86e648" - integrity sha512-dY789wq6l0uLY8py9c1B48V8mVL5gZh/+PQ5ZPrylPYsnAvnEMjqsUXkuoDVPeVK+0VyGar+D08107LzDQ6pag== +"@babel/plugin-transform-modules-commonjs@^7.12.1", "@babel/plugin-transform-modules-commonjs@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.12.13.tgz#5043b870a784a8421fa1fd9136a24f294da13e50" + integrity sha512-OGQoeVXVi1259HjuoDnsQMlMkT9UkZT9TpXAsqWplS/M0N1g3TJAn/ByOCeQu7mfjc5WpSsRU+jV1Hd89ts0kQ== dependencies: - "@babel/helper-module-transforms" "^7.12.1" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-simple-access" "^7.12.1" + "@babel/helper-module-transforms" "^7.12.13" + "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-simple-access" "^7.12.13" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-systemjs@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.12.1.tgz#663fea620d593c93f214a464cd399bf6dc683086" - integrity sha512-Hn7cVvOavVh8yvW6fLwveFqSnd7rbQN3zJvoPNyNaQSvgfKmDBO9U1YL9+PCXGRlZD9tNdWTy5ACKqMuzyn32Q== +"@babel/plugin-transform-modules-systemjs@^7.12.1", "@babel/plugin-transform-modules-systemjs@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.12.13.tgz#351937f392c7f07493fc79b2118201d50404a3c5" + integrity sha512-aHfVjhZ8QekaNF/5aNdStCGzwTbU7SI5hUybBKlMzqIMC7w7Ho8hx5a4R/DkTHfRfLwHGGxSpFt9BfxKCoXKoA== dependencies: - "@babel/helper-hoist-variables" "^7.10.4" - "@babel/helper-module-transforms" "^7.12.1" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-validator-identifier" "^7.10.4" + "@babel/helper-hoist-variables" "^7.12.13" + "@babel/helper-module-transforms" "^7.12.13" + "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-validator-identifier" "^7.12.11" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-umd@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.12.1.tgz#eb5a218d6b1c68f3d6217b8fa2cc82fec6547902" - integrity sha512-aEIubCS0KHKM0zUos5fIoQm+AZUMt1ZvMpqz0/H5qAQ7vWylr9+PLYurT+Ic7ID/bKLd4q8hDovaG3Zch2uz5Q== +"@babel/plugin-transform-modules-umd@^7.12.1", "@babel/plugin-transform-modules-umd@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.12.13.tgz#26c66f161d3456674e344b4b1255de4d530cfb37" + integrity sha512-BgZndyABRML4z6ibpi7Z98m4EVLFI9tVsZDADC14AElFaNHHBcJIovflJ6wtCqFxwy2YJ1tJhGRsr0yLPKoN+w== dependencies: - "@babel/helper-module-transforms" "^7.12.1" - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-module-transforms" "^7.12.13" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-named-capturing-groups-regex@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.1.tgz#b407f5c96be0d9f5f88467497fa82b30ac3e8753" - integrity sha512-tB43uQ62RHcoDp9v2Nsf+dSM8sbNodbEicbQNA53zHz8pWUhsgHSJCGpt7daXxRydjb0KnfmB+ChXOv3oADp1Q== +"@babel/plugin-transform-named-capturing-groups-regex@^7.12.1", "@babel/plugin-transform-named-capturing-groups-regex@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.13.tgz#2213725a5f5bbbe364b50c3ba5998c9599c5c9d9" + integrity sha512-Xsm8P2hr5hAxyYblrfACXpQKdQbx4m2df9/ZZSQ8MAhsadw06+jW7s9zsSw6he+mJZXRlVMyEnVktJo4zjk1WA== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.12.1" + "@babel/helper-create-regexp-features-plugin" "^7.12.13" -"@babel/plugin-transform-new-target@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.1.tgz#80073f02ee1bb2d365c3416490e085c95759dec0" - integrity sha512-+eW/VLcUL5L9IvJH7rT1sT0CzkdUTvPrXC2PXTn/7z7tXLBuKvezYbGdxD5WMRoyvyaujOq2fWoKl869heKjhw== +"@babel/plugin-transform-new-target@^7.12.1", "@babel/plugin-transform-new-target@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.13.tgz#e22d8c3af24b150dd528cbd6e685e799bf1c351c" + integrity sha512-/KY2hbLxrG5GTQ9zzZSc3xWiOy379pIETEhbtzwZcw9rvuaVV4Fqy7BYGYOWZnaoXIQYbbJ0ziXLa/sKcGCYEQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-object-super@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.1.tgz#4ea08696b8d2e65841d0c7706482b048bed1066e" - integrity sha512-AvypiGJH9hsquNUn+RXVcBdeE3KHPZexWRdimhuV59cSoOt5kFBmqlByorAeUlGG2CJWd0U+4ZtNKga/TB0cAw== +"@babel/plugin-transform-object-super@^7.12.1", "@babel/plugin-transform-object-super@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.13.tgz#b4416a2d63b8f7be314f3d349bd55a9c1b5171f7" + integrity sha512-JzYIcj3XtYspZDV8j9ulnoMPZZnF/Cj0LUxPOjR89BdBVx+zYJI9MdMIlUZjbXDX+6YVeS6I3e8op+qQ3BYBoQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-replace-supers" "^7.12.1" + "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-replace-supers" "^7.12.13" -"@babel/plugin-transform-parameters@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.12.1.tgz#d2e963b038771650c922eff593799c96d853255d" - integrity sha512-xq9C5EQhdPK23ZeCdMxl8bbRnAgHFrw5EOC3KJUsSylZqdkCaFEXxGSBuTSObOpiiHHNyb82es8M1QYgfQGfNg== +"@babel/plugin-transform-parameters@^7.12.1", "@babel/plugin-transform-parameters@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.12.13.tgz#461e76dfb63c2dfd327b8a008a9e802818ce9853" + integrity sha512-e7QqwZalNiBRHCpJg/P8s/VJeSRYgmtWySs1JwvfwPqhBbiWfOcHDKdeAi6oAyIimoKWBlwc8oTgbZHdhCoVZA== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-property-literals@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.1.tgz#41bc81200d730abb4456ab8b3fbd5537b59adecd" - integrity sha512-6MTCR/mZ1MQS+AwZLplX4cEySjCpnIF26ToWo942nqn8hXSm7McaHQNeGx/pt7suI1TWOWMfa/NgBhiqSnX0cQ== +"@babel/plugin-transform-property-literals@^7.12.1", "@babel/plugin-transform-property-literals@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.13.tgz#4e6a9e37864d8f1b3bc0e2dce7bf8857db8b1a81" + integrity sha512-nqVigwVan+lR+g8Fj8Exl0UQX2kymtjcWfMOYM1vTYEKujeyv2SkMgazf2qNcK7l4SDiKyTA/nHCPqL4e2zo1A== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-react-constant-elements@^7.9.0": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.12.1.tgz#4471f0851feec3231cc9aaa0dccde39947c1ac1e" - integrity sha512-KOHd0tIRLoER+J+8f9DblZDa1fLGPwaaN1DI1TVHuQFOpjHV22C3CUB3obeC4fexHY9nx+fH0hQNvLFFfA1mxA== + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.12.13.tgz#f8ee56888545d53d80f766b3cc1563ab2c241f92" + integrity sha512-qmzKVTn46Upvtxv8LQoQ8mTCdUC83AOVQIQm57e9oekLT5cmK9GOMOfcWhe8jMNx4UJXn/UDhVZ/7lGofVNeDQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-react-display-name@7.12.1", "@babel/plugin-transform-react-display-name@^7.12.1": +"@babel/plugin-transform-react-display-name@7.12.1": version "7.12.1" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.12.1.tgz#1cbcd0c3b1d6648c55374a22fc9b6b7e5341c00d" integrity sha512-cAzB+UzBIrekfYxyLlFqf/OagTvHLcVBb5vpouzkYkBclRPraiygVnafvAoipErZLI8ANv8Ecn6E/m5qPXD26w== dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-react-jsx-development@^7.12.1", "@babel/plugin-transform-react-jsx-development@^7.12.7": +"@babel/plugin-transform-react-display-name@^7.12.1", "@babel/plugin-transform-react-display-name@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.12.13.tgz#c28effd771b276f4647411c9733dbb2d2da954bd" + integrity sha512-MprESJzI9O5VnJZrL7gg1MpdqmiFcUv41Jc7SahxYsNP2kDkFqClxxTZq+1Qv4AFCamm+GXMRDQINNn+qrxmiA== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-transform-react-jsx-development@^7.12.1", "@babel/plugin-transform-react-jsx-development@^7.12.12": version "7.12.12" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.12.12.tgz#bccca33108fe99d95d7f9e82046bfe762e71f4e7" integrity sha512-i1AxnKxHeMxUaWVXQOSIco4tvVvvCxMSfeBMnMM06mpaJt3g+MpxYQQrDfojUQldP1xxraPSJYSMEljoWM/dCg== @@ -753,29 +766,29 @@ "@babel/plugin-transform-react-jsx" "^7.12.12" "@babel/plugin-transform-react-jsx-self@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.12.1.tgz#ef43cbca2a14f1bd17807dbe4376ff89d714cf28" - integrity sha512-FbpL0ieNWiiBB5tCldX17EtXgmzeEZjFrix72rQYeq9X6nUK38HCaxexzVQrZWXanxKJPKVVIU37gFjEQYkPkA== + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.12.13.tgz#422d99d122d592acab9c35ea22a6cfd9bf189f60" + integrity sha512-FXYw98TTJ125GVCCkFLZXlZ1qGcsYqNQhVBQcZjyrwf8FEUtVfKIoidnO8S0q+KBQpDYNTmiGo1gn67Vti04lQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-react-jsx-source@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.12.1.tgz#d07de6863f468da0809edcf79a1aa8ce2a82a26b" - integrity sha512-keQ5kBfjJNRc6zZN1/nVHCd6LLIHq4aUKcVnvE/2l+ZZROSbqoiGFRtT5t3Is89XJxBQaP7NLZX2jgGHdZvvFQ== + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.12.13.tgz#051d76126bee5c9a6aa3ba37be2f6c1698856bcb" + integrity sha512-O5JJi6fyfih0WfDgIJXksSPhGP/G0fQpfxYy87sDc+1sFmsCS6wr3aAn+whbzkhbjtq4VMqLRaSzR6IsshIC0Q== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-react-jsx@^7.12.1", "@babel/plugin-transform-react-jsx@^7.12.10", "@babel/plugin-transform-react-jsx@^7.12.12": - version "7.12.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.12.12.tgz#b0da51ffe5f34b9a900e9f1f5fb814f9e512d25e" - integrity sha512-JDWGuzGNWscYcq8oJVCtSE61a5+XAOos+V0HrxnDieUus4UMnBEosDnY1VJqU5iZ4pA04QY7l0+JvHL1hZEfsw== +"@babel/plugin-transform-react-jsx@^7.12.1", "@babel/plugin-transform-react-jsx@^7.12.12", "@babel/plugin-transform-react-jsx@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.12.13.tgz#6c9f993b9f6fb6f0e32a4821ed59349748576a3e" + integrity sha512-hhXZMYR8t9RvduN2uW4sjl6MRtUhzNE726JvoJhpjhxKgRUVkZqTsA0xc49ALZxQM7H26pZ/lLvB2Yrea9dllA== dependencies: - "@babel/helper-annotate-as-pure" "^7.12.10" - "@babel/helper-module-imports" "^7.12.5" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-jsx" "^7.12.1" - "@babel/types" "^7.12.12" + "@babel/helper-annotate-as-pure" "^7.12.13" + "@babel/helper-module-imports" "^7.12.13" + "@babel/helper-plugin-utils" "^7.12.13" + "@babel/plugin-syntax-jsx" "^7.12.13" + "@babel/types" "^7.12.13" "@babel/plugin-transform-react-pure-annotations@^7.12.1": version "7.12.1" @@ -785,19 +798,19 @@ "@babel/helper-annotate-as-pure" "^7.10.4" "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-regenerator@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.12.1.tgz#5f0a28d842f6462281f06a964e88ba8d7ab49753" - integrity sha512-gYrHqs5itw6i4PflFX3OdBPMQdPbF4bj2REIUxlMRUFk0/ZOAIpDFuViuxPjUL7YC8UPnf+XG7/utJvqXdPKng== +"@babel/plugin-transform-regenerator@^7.12.1", "@babel/plugin-transform-regenerator@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.12.13.tgz#b628bcc9c85260ac1aeb05b45bde25210194a2f5" + integrity sha512-lxb2ZAvSLyJ2PEe47hoGWPmW22v7CtSl9jW8mingV4H2sEX/JOcrAj2nPuGWi56ERUm2bUpjKzONAuT6HCn2EA== dependencies: regenerator-transform "^0.14.2" -"@babel/plugin-transform-reserved-words@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.1.tgz#6fdfc8cc7edcc42b36a7c12188c6787c873adcd8" - integrity sha512-pOnUfhyPKvZpVyBHhSBoX8vfA09b7r00Pmm1sH+29ae2hMTKVmSp4Ztsr8KBKjLjx17H0eJqaRC3bR2iThM54A== +"@babel/plugin-transform-reserved-words@^7.12.1", "@babel/plugin-transform-reserved-words@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.13.tgz#7d9988d4f06e0fe697ea1d9803188aa18b472695" + integrity sha512-xhUPzDXxZN1QfiOy/I5tyye+TRz6lA7z6xaT4CLOjPRMVg1ldRf0LHw0TDBpYL4vG78556WuHdyO9oi5UmzZBg== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-runtime@7.12.1": version "7.12.1" @@ -809,65 +822,65 @@ resolve "^1.8.1" semver "^5.5.1" -"@babel/plugin-transform-shorthand-properties@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.1.tgz#0bf9cac5550fce0cfdf043420f661d645fdc75e3" - integrity sha512-GFZS3c/MhX1OusqB1MZ1ct2xRzX5ppQh2JU1h2Pnfk88HtFTM+TWQqJNfwkmxtPQtb/s1tk87oENfXJlx7rSDw== +"@babel/plugin-transform-shorthand-properties@^7.12.1", "@babel/plugin-transform-shorthand-properties@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.13.tgz#db755732b70c539d504c6390d9ce90fe64aff7ad" + integrity sha512-xpL49pqPnLtf0tVluuqvzWIgLEhuPpZzvs2yabUHSKRNlN7ScYU7aMlmavOeyXJZKgZKQRBlh8rHbKiJDraTSw== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-spread@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.12.1.tgz#527f9f311be4ec7fdc2b79bb89f7bf884b3e1e1e" - integrity sha512-vuLp8CP0BE18zVYjsEBZ5xoCecMK6LBMMxYzJnh01rxQRvhNhH1csMMmBfNo5tGpGO+NhdSNW2mzIvBu3K1fng== +"@babel/plugin-transform-spread@^7.12.1", "@babel/plugin-transform-spread@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.12.13.tgz#ca0d5645abbd560719c354451b849f14df4a7949" + integrity sha512-dUCrqPIowjqk5pXsx1zPftSq4sT0aCeZVAxhdgs3AMgyaDmoUT0G+5h3Dzja27t76aUEIJWlFgPJqJ/d4dbTtg== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" -"@babel/plugin-transform-sticky-regex@^7.12.1", "@babel/plugin-transform-sticky-regex@^7.12.7": - version "7.12.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.7.tgz#560224613ab23987453948ed21d0b0b193fa7fad" - integrity sha512-VEiqZL5N/QvDbdjfYQBhruN0HYjSPjC4XkeqW4ny/jNtH9gcbgaqBIXYEZCNnESMAGs0/K/R7oFGMhOyu/eIxg== +"@babel/plugin-transform-sticky-regex@^7.12.1", "@babel/plugin-transform-sticky-regex@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.13.tgz#760ffd936face73f860ae646fb86ee82f3d06d1f" + integrity sha512-Jc3JSaaWT8+fr7GRvQP02fKDsYk4K/lYwWq38r/UGfaxo89ajud321NH28KRQ7xy1Ybc0VUE5Pz8psjNNDUglg== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-template-literals@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.12.1.tgz#b43ece6ed9a79c0c71119f576d299ef09d942843" - integrity sha512-b4Zx3KHi+taXB1dVRBhVJtEPi9h1THCeKmae2qP0YdUHIFhVjtpqqNfxeVAa1xeHVhAy4SbHxEwx5cltAu5apw== +"@babel/plugin-transform-template-literals@^7.12.1", "@babel/plugin-transform-template-literals@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.12.13.tgz#655037b07ebbddaf3b7752f55d15c2fd6f5aa865" + integrity sha512-arIKlWYUgmNsF28EyfmiQHJLJFlAJNYkuQO10jL46ggjBpeb2re1P9K9YGxNJB45BqTbaslVysXDYm/g3sN/Qg== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-typeof-symbol@^7.12.1", "@babel/plugin-transform-typeof-symbol@^7.12.10": - version "7.12.10" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.10.tgz#de01c4c8f96580bd00f183072b0d0ecdcf0dec4b" - integrity sha512-JQ6H8Rnsogh//ijxspCjc21YPd3VLVoYtAwv3zQmqAt8YGYUtdo5usNhdl4b9/Vir2kPFZl6n1h0PfUz4hJhaA== +"@babel/plugin-transform-typeof-symbol@^7.12.1", "@babel/plugin-transform-typeof-symbol@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.13.tgz#785dd67a1f2ea579d9c2be722de8c84cb85f5a7f" + integrity sha512-eKv/LmUJpMnu4npgfvs3LiHhJua5fo/CysENxa45YCQXZwKnGCQKAg87bvoqSW1fFT+HA32l03Qxsm8ouTY3ZQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-typescript@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.12.1.tgz#d92cc0af504d510e26a754a7dbc2e5c8cd9c7ab4" - integrity sha512-VrsBByqAIntM+EYMqSm59SiMEf7qkmI9dqMt6RbD/wlwueWmYcI0FFK5Fj47pP6DRZm+3teXjosKlwcZJ5lIMw== + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.12.13.tgz#8bcb5dd79cb8bba690d6920e19992d9228dfed48" + integrity sha512-z1VWskPJxK9tfxoYvePWvzSJC+4pxXr8ArmRm5ofqgi+mwpKg6lvtomkIngBYMJVnKhsFYVysCQLDn//v2RHcg== dependencies: - "@babel/helper-create-class-features-plugin" "^7.12.1" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-typescript" "^7.12.1" + "@babel/helper-create-class-features-plugin" "^7.12.13" + "@babel/helper-plugin-utils" "^7.12.13" + "@babel/plugin-syntax-typescript" "^7.12.13" -"@babel/plugin-transform-unicode-escapes@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.1.tgz#5232b9f81ccb07070b7c3c36c67a1b78f1845709" - integrity sha512-I8gNHJLIc7GdApm7wkVnStWssPNbSRMPtgHdmH3sRM1zopz09UWPS4x5V4n1yz/MIWTVnJ9sp6IkuXdWM4w+2Q== +"@babel/plugin-transform-unicode-escapes@^7.12.1", "@babel/plugin-transform-unicode-escapes@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.13.tgz#840ced3b816d3b5127dd1d12dcedc5dead1a5e74" + integrity sha512-0bHEkdwJ/sN/ikBHfSmOXPypN/beiGqjo+o4/5K+vxEFNPRPdImhviPakMKG4x96l85emoa0Z6cDflsdBusZbw== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-unicode-regex@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.1.tgz#cc9661f61390db5c65e3febaccefd5c6ac3faecb" - integrity sha512-SqH4ClNngh/zGwHZOOQMTD+e8FGWexILV+ePMyiDJttAWRh5dhDL8rcl5lSgU3Huiq6Zn6pWTMvdPAb21Dwdyg== +"@babel/plugin-transform-unicode-regex@^7.12.1", "@babel/plugin-transform-unicode-regex@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.13.tgz#b52521685804e155b1202e83fc188d34bb70f5ac" + integrity sha512-mDRzSNY7/zopwisPZ5kM9XKCfhchqIYwAKRERtEnhYscZB79VRekuRSoYbN0+KVe3y8+q1h6A4svXtP7N+UoCA== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.12.1" - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-create-regexp-features-plugin" "^7.12.13" + "@babel/helper-plugin-utils" "^7.12.13" "@babel/preset-env@7.12.1": version "7.12.1" @@ -942,30 +955,30 @@ semver "^5.5.0" "@babel/preset-env@^7.8.4", "@babel/preset-env@^7.9.5": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.12.11.tgz#55d5f7981487365c93dbbc84507b1c7215e857f9" - integrity sha512-j8Tb+KKIXKYlDBQyIOy4BLxzv1NUOwlHfZ74rvW+Z0Gp4/cI2IMDPBWAgWceGcE7aep9oL/0K9mlzlMGxA8yNw== - dependencies: - "@babel/compat-data" "^7.12.7" - "@babel/helper-compilation-targets" "^7.12.5" - "@babel/helper-module-imports" "^7.12.5" - "@babel/helper-plugin-utils" "^7.10.4" + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.12.13.tgz#3aa2d09cf7d255177538dff292ac9af29ad46525" + integrity sha512-JUVlizG8SoFTz4LmVUL8++aVwzwxcvey3N0j1tRbMAXVEy95uQ/cnEkmEKHN00Bwq4voAV3imQGnQvpkLAxsrw== + dependencies: + "@babel/compat-data" "^7.12.13" + "@babel/helper-compilation-targets" "^7.12.13" + "@babel/helper-module-imports" "^7.12.13" + "@babel/helper-plugin-utils" "^7.12.13" "@babel/helper-validator-option" "^7.12.11" - "@babel/plugin-proposal-async-generator-functions" "^7.12.1" - "@babel/plugin-proposal-class-properties" "^7.12.1" + "@babel/plugin-proposal-async-generator-functions" "^7.12.13" + "@babel/plugin-proposal-class-properties" "^7.12.13" "@babel/plugin-proposal-dynamic-import" "^7.12.1" - "@babel/plugin-proposal-export-namespace-from" "^7.12.1" - "@babel/plugin-proposal-json-strings" "^7.12.1" - "@babel/plugin-proposal-logical-assignment-operators" "^7.12.1" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.12.1" - "@babel/plugin-proposal-numeric-separator" "^7.12.7" - "@babel/plugin-proposal-object-rest-spread" "^7.12.1" - "@babel/plugin-proposal-optional-catch-binding" "^7.12.1" - "@babel/plugin-proposal-optional-chaining" "^7.12.7" - "@babel/plugin-proposal-private-methods" "^7.12.1" - "@babel/plugin-proposal-unicode-property-regex" "^7.12.1" + "@babel/plugin-proposal-export-namespace-from" "^7.12.13" + "@babel/plugin-proposal-json-strings" "^7.12.13" + "@babel/plugin-proposal-logical-assignment-operators" "^7.12.13" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.12.13" + "@babel/plugin-proposal-numeric-separator" "^7.12.13" + "@babel/plugin-proposal-object-rest-spread" "^7.12.13" + "@babel/plugin-proposal-optional-catch-binding" "^7.12.13" + "@babel/plugin-proposal-optional-chaining" "^7.12.13" + "@babel/plugin-proposal-private-methods" "^7.12.13" + "@babel/plugin-proposal-unicode-property-regex" "^7.12.13" "@babel/plugin-syntax-async-generators" "^7.8.0" - "@babel/plugin-syntax-class-properties" "^7.12.1" + "@babel/plugin-syntax-class-properties" "^7.12.13" "@babel/plugin-syntax-dynamic-import" "^7.8.0" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" "@babel/plugin-syntax-json-strings" "^7.8.0" @@ -975,41 +988,41 @@ "@babel/plugin-syntax-object-rest-spread" "^7.8.0" "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" "@babel/plugin-syntax-optional-chaining" "^7.8.0" - "@babel/plugin-syntax-top-level-await" "^7.12.1" - "@babel/plugin-transform-arrow-functions" "^7.12.1" - "@babel/plugin-transform-async-to-generator" "^7.12.1" - "@babel/plugin-transform-block-scoped-functions" "^7.12.1" - "@babel/plugin-transform-block-scoping" "^7.12.11" - "@babel/plugin-transform-classes" "^7.12.1" - "@babel/plugin-transform-computed-properties" "^7.12.1" - "@babel/plugin-transform-destructuring" "^7.12.1" - "@babel/plugin-transform-dotall-regex" "^7.12.1" - "@babel/plugin-transform-duplicate-keys" "^7.12.1" - "@babel/plugin-transform-exponentiation-operator" "^7.12.1" - "@babel/plugin-transform-for-of" "^7.12.1" - "@babel/plugin-transform-function-name" "^7.12.1" - "@babel/plugin-transform-literals" "^7.12.1" - "@babel/plugin-transform-member-expression-literals" "^7.12.1" - "@babel/plugin-transform-modules-amd" "^7.12.1" - "@babel/plugin-transform-modules-commonjs" "^7.12.1" - "@babel/plugin-transform-modules-systemjs" "^7.12.1" - "@babel/plugin-transform-modules-umd" "^7.12.1" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.12.1" - "@babel/plugin-transform-new-target" "^7.12.1" - "@babel/plugin-transform-object-super" "^7.12.1" - "@babel/plugin-transform-parameters" "^7.12.1" - "@babel/plugin-transform-property-literals" "^7.12.1" - "@babel/plugin-transform-regenerator" "^7.12.1" - "@babel/plugin-transform-reserved-words" "^7.12.1" - "@babel/plugin-transform-shorthand-properties" "^7.12.1" - "@babel/plugin-transform-spread" "^7.12.1" - "@babel/plugin-transform-sticky-regex" "^7.12.7" - "@babel/plugin-transform-template-literals" "^7.12.1" - "@babel/plugin-transform-typeof-symbol" "^7.12.10" - "@babel/plugin-transform-unicode-escapes" "^7.12.1" - "@babel/plugin-transform-unicode-regex" "^7.12.1" + "@babel/plugin-syntax-top-level-await" "^7.12.13" + "@babel/plugin-transform-arrow-functions" "^7.12.13" + "@babel/plugin-transform-async-to-generator" "^7.12.13" + "@babel/plugin-transform-block-scoped-functions" "^7.12.13" + "@babel/plugin-transform-block-scoping" "^7.12.13" + "@babel/plugin-transform-classes" "^7.12.13" + "@babel/plugin-transform-computed-properties" "^7.12.13" + "@babel/plugin-transform-destructuring" "^7.12.13" + "@babel/plugin-transform-dotall-regex" "^7.12.13" + "@babel/plugin-transform-duplicate-keys" "^7.12.13" + "@babel/plugin-transform-exponentiation-operator" "^7.12.13" + "@babel/plugin-transform-for-of" "^7.12.13" + "@babel/plugin-transform-function-name" "^7.12.13" + "@babel/plugin-transform-literals" "^7.12.13" + "@babel/plugin-transform-member-expression-literals" "^7.12.13" + "@babel/plugin-transform-modules-amd" "^7.12.13" + "@babel/plugin-transform-modules-commonjs" "^7.12.13" + "@babel/plugin-transform-modules-systemjs" "^7.12.13" + "@babel/plugin-transform-modules-umd" "^7.12.13" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.12.13" + "@babel/plugin-transform-new-target" "^7.12.13" + "@babel/plugin-transform-object-super" "^7.12.13" + "@babel/plugin-transform-parameters" "^7.12.13" + "@babel/plugin-transform-property-literals" "^7.12.13" + "@babel/plugin-transform-regenerator" "^7.12.13" + "@babel/plugin-transform-reserved-words" "^7.12.13" + "@babel/plugin-transform-shorthand-properties" "^7.12.13" + "@babel/plugin-transform-spread" "^7.12.13" + "@babel/plugin-transform-sticky-regex" "^7.12.13" + "@babel/plugin-transform-template-literals" "^7.12.13" + "@babel/plugin-transform-typeof-symbol" "^7.12.13" + "@babel/plugin-transform-unicode-escapes" "^7.12.13" + "@babel/plugin-transform-unicode-regex" "^7.12.13" "@babel/preset-modules" "^0.1.3" - "@babel/types" "^7.12.11" + "@babel/types" "^7.12.13" core-js-compat "^3.8.0" semver "^5.5.0" @@ -1038,14 +1051,14 @@ "@babel/plugin-transform-react-pure-annotations" "^7.12.1" "@babel/preset-react@^7.9.4": - version "7.12.10" - resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.12.10.tgz#4fed65f296cbb0f5fb09de6be8cddc85cc909be9" - integrity sha512-vtQNjaHRl4DUpp+t+g4wvTHsLQuye+n0H/wsXIZRn69oz/fvNC7gQ4IK73zGJBaxvHoxElDvnYCthMcT7uzFoQ== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-transform-react-display-name" "^7.12.1" - "@babel/plugin-transform-react-jsx" "^7.12.10" - "@babel/plugin-transform-react-jsx-development" "^7.12.7" + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.12.13.tgz#5f911b2eb24277fa686820d5bd81cad9a0602a0a" + integrity sha512-TYM0V9z6Abb6dj1K7i5NrEhA13oS5ujUYQYDfqIBXYHOc2c2VkFgc+q9kyssIyUfy4/hEwqrgSlJ/Qgv8zJLsA== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + "@babel/plugin-transform-react-display-name" "^7.12.13" + "@babel/plugin-transform-react-jsx" "^7.12.13" + "@babel/plugin-transform-react-jsx-development" "^7.12.12" "@babel/plugin-transform-react-pure-annotations" "^7.12.1" "@babel/preset-typescript@7.12.1": @@ -1057,9 +1070,9 @@ "@babel/plugin-transform-typescript" "^7.12.1" "@babel/runtime-corejs3@^7.10.2": - version "7.12.5" - resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.12.5.tgz#ffee91da0eb4c6dae080774e94ba606368e414f4" - integrity sha512-roGr54CsTmNPPzZoCP1AmDXuBoNao7tnSA83TXTwt+UK5QVyh1DIJnrgYRPWKCF2flqZQXwa7Yr8v7VmLzF0YQ== + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.12.13.tgz#53d09813b7c20d616caf258e9325550ff701c039" + integrity sha512-8fSpqYRETHATtNitsCXq8QQbKJP31/KnDl2Wz2Vtui9nKzjss2ysuZtyVsWjBtvkeEFo346gkwjYPab1hvrXkQ== dependencies: core-js-pure "^3.0.0" regenerator-runtime "^0.13.4" @@ -1093,40 +1106,40 @@ regenerator-runtime "^0.12.0" "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.0", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7": - version "7.12.5" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.5.tgz#410e7e487441e1b360c29be715d870d9b985882e" - integrity sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg== + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.13.tgz#0a21452352b02542db0ffb928ac2d3ca7cb6d66d" + integrity sha512-8+3UMPBrjFa/6TtKi/7sehPKqfAm4g6K+YQjyyFOLUTxzOngcRZTlAVY8sc2CORJYqdHQY8gRPHmn+qo15rCBw== dependencies: regenerator-runtime "^0.13.4" -"@babel/template@^7.10.4", "@babel/template@^7.12.7", "@babel/template@^7.3.3": - version "7.12.7" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.7.tgz#c817233696018e39fbb6c491d2fb684e05ed43bc" - integrity sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/parser" "^7.12.7" - "@babel/types" "^7.12.7" - -"@babel/traverse@^7.1.0", "@babel/traverse@^7.10.4", "@babel/traverse@^7.12.1", "@babel/traverse@^7.12.10", "@babel/traverse@^7.12.5", "@babel/traverse@^7.7.0": - version "7.12.12" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.12.tgz#d0cd87892704edd8da002d674bc811ce64743376" - integrity sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w== - dependencies: - "@babel/code-frame" "^7.12.11" - "@babel/generator" "^7.12.11" - "@babel/helper-function-name" "^7.12.11" - "@babel/helper-split-export-declaration" "^7.12.11" - "@babel/parser" "^7.12.11" - "@babel/types" "^7.12.12" +"@babel/template@^7.10.4", "@babel/template@^7.12.13", "@babel/template@^7.3.3": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.13.tgz#530265be8a2589dbb37523844c5bcb55947fb327" + integrity sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA== + dependencies: + "@babel/code-frame" "^7.12.13" + "@babel/parser" "^7.12.13" + "@babel/types" "^7.12.13" + +"@babel/traverse@^7.1.0", "@babel/traverse@^7.12.1", "@babel/traverse@^7.12.13", "@babel/traverse@^7.7.0": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.13.tgz#689f0e4b4c08587ad26622832632735fb8c4e0c0" + integrity sha512-3Zb4w7eE/OslI0fTp8c7b286/cQps3+vdLW3UcwC8VSJC6GbKn55aeVVu2QJNuCDoeKyptLOFrPq8WqZZBodyA== + dependencies: + "@babel/code-frame" "^7.12.13" + "@babel/generator" "^7.12.13" + "@babel/helper-function-name" "^7.12.13" + "@babel/helper-split-export-declaration" "^7.12.13" + "@babel/parser" "^7.12.13" + "@babel/types" "^7.12.13" debug "^4.1.0" globals "^11.1.0" lodash "^4.17.19" -"@babel/types@^7.0.0", "@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.12.1", "@babel/types@^7.12.10", "@babel/types@^7.12.11", "@babel/types@^7.12.12", "@babel/types@^7.12.5", "@babel/types@^7.12.6", "@babel/types@^7.12.7", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4", "@babel/types@^7.7.0": - version "7.12.12" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.12.tgz#4608a6ec313abbd87afa55004d373ad04a96c299" - integrity sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ== +"@babel/types@^7.0.0", "@babel/types@^7.12.1", "@babel/types@^7.12.13", "@babel/types@^7.12.6", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4", "@babel/types@^7.7.0": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.13.tgz#8be1aa8f2c876da11a9cf650c0ecf656913ad611" + integrity sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ== dependencies: "@babel/helper-validator-identifier" "^7.12.11" lodash "^4.17.19" @@ -1447,7 +1460,7 @@ dependencies: "@babel/runtime" "^7.4.4" -"@material-ui/styles@^4.10.0": +"@material-ui/styles@4.11.3", "@material-ui/styles@^4.10.0": version "4.11.3" resolved "https://registry.yarnpkg.com/@material-ui/styles/-/styles-4.11.3.tgz#1b8d97775a4a643b53478c895e3f2a464e8916f2" integrity sha512-HzVzCG+PpgUGMUYEJ2rTEmQYeonGh41BYfILNFb/1ueqma+p1meSdu4RX6NjxYBMhf7k+jgfHFTTz+L1SXL/Zg== @@ -1896,9 +1909,9 @@ integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== "@types/node@*": - version "14.14.22" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.22.tgz#0d29f382472c4ccf3bd96ff0ce47daf5b7b84b18" - integrity sha512-g+f/qj/cNcqKkc3tFqlXOYjrmZA+jNBiDzbP3kH+B+otKFqAdPgVTGP1IeKRdMml/aE69as5S4FqtxAbl+LaMw== + version "14.14.24" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.24.tgz#541c00e4f7c41c8f108bd5b045248b5224c62946" + integrity sha512-6BAlkS4seVjszhrwN0W1WabqWwuJwcYF36Z1rPPyQm80LGRKsIeUPdzI51TezXenjetFNy1gRTpuDn1NBg33LA== "@types/node@14.6.4": version "14.6.4" @@ -1974,9 +1987,9 @@ "@types/react" "*" "@types/react@*": - version "17.0.0" - resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.0.tgz#5af3eb7fad2807092f0046a1302b7823e27919b8" - integrity sha512-aj/L7RIMsRlWML3YB6KZiXB3fV2t41+5RBGYF8z+tAKU43Px8C3cYUZsDvf1/+Bm4FK21QWBrDutu8ZJ/70qOw== + version "17.0.1" + resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.1.tgz#eb1f1407dea8da3bc741879c1192aa703ab9975b" + integrity sha512-w8t9f53B2ei4jeOqf/gxtc2Sswnc3LBK5s0DyJcg5xd10tMHXts2N31cKjWfH9IC/JvEPa/YF1U4YeP1t4R6HQ== dependencies: "@types/prop-types" "*" csstype "^3.0.2" @@ -2081,6 +2094,20 @@ dependencies: "@types/yargs-parser" "*" +"@typescript-eslint/eslint-plugin@4.14.1": + version "4.14.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.14.1.tgz#22dd301ce228aaab3416b14ead10b1db3e7d3180" + integrity sha512-5JriGbYhtqMS1kRcZTQxndz1lKMwwEXKbwZbkUZNnp6MJX0+OVXnG0kOlBZP4LUAxEyzu3cs+EXd/97MJXsGfw== + dependencies: + "@typescript-eslint/experimental-utils" "4.14.1" + "@typescript-eslint/scope-manager" "4.14.1" + debug "^4.1.1" + functional-red-black-tree "^1.0.1" + lodash "^4.17.15" + regexpp "^3.0.0" + semver "^7.3.2" + tsutils "^3.17.1" + "@typescript-eslint/eslint-plugin@^4.5.0": version "4.14.2" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.14.2.tgz#47a15803cfab89580b96933d348c2721f3d2f6fe" @@ -2095,6 +2122,18 @@ semver "^7.3.2" tsutils "^3.17.1" +"@typescript-eslint/experimental-utils@4.14.1": + version "4.14.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.14.1.tgz#a5c945cb24dabb96747180e1cfc8487f8066f471" + integrity sha512-2CuHWOJwvpw0LofbyG5gvYjEyoJeSvVH2PnfUQSn0KQr4v8Dql2pr43ohmx4fdPQ/eVoTSFjTi/bsGEXl/zUUQ== + dependencies: + "@types/json-schema" "^7.0.3" + "@typescript-eslint/scope-manager" "4.14.1" + "@typescript-eslint/types" "4.14.1" + "@typescript-eslint/typescript-estree" "4.14.1" + eslint-scope "^5.0.0" + eslint-utils "^2.0.0" + "@typescript-eslint/experimental-utils@4.14.2", "@typescript-eslint/experimental-utils@^4.0.1": version "4.14.2" resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.14.2.tgz#9df35049d1d36b6cbaba534d703648b9e1f05cbb" @@ -2118,6 +2157,26 @@ eslint-scope "^5.0.0" eslint-utils "^2.0.0" +"@typescript-eslint/parser@4.14.1": + version "4.14.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.14.1.tgz#3bd6c24710cd557d8446625284bcc9c6d52817c6" + integrity sha512-mL3+gU18g9JPsHZuKMZ8Z0Ss9YP1S5xYZ7n68Z98GnPq02pYNQuRXL85b9GYhl6jpdvUc45Km7hAl71vybjUmw== + dependencies: + "@typescript-eslint/scope-manager" "4.14.1" + "@typescript-eslint/types" "4.14.1" + "@typescript-eslint/typescript-estree" "4.14.1" + debug "^4.1.1" + +"@typescript-eslint/parser@4.4.1": + version "4.4.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.4.1.tgz#25fde9c080611f303f2f33cedb145d2c59915b80" + integrity sha512-S0fuX5lDku28Au9REYUsV+hdJpW/rNW0gWlc4SXzF/kdrRaAVX9YCxKpziH7djeWT/HFAjLZcnY7NJD8xTeUEg== + dependencies: + "@typescript-eslint/scope-manager" "4.4.1" + "@typescript-eslint/types" "4.4.1" + "@typescript-eslint/typescript-estree" "4.4.1" + debug "^4.1.1" + "@typescript-eslint/parser@^4.5.0": version "4.14.2" resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.14.2.tgz#31e216e4baab678a56e539f9db9862e2542c98d0" @@ -2128,6 +2187,14 @@ "@typescript-eslint/typescript-estree" "4.14.2" debug "^4.1.1" +"@typescript-eslint/scope-manager@4.14.1": + version "4.14.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.14.1.tgz#8444534254c6f370e9aa974f035ced7fe713ce02" + integrity sha512-F4bjJcSqXqHnC9JGUlnqSa3fC2YH5zTtmACS1Hk+WX/nFB0guuynVK5ev35D4XZbdKjulXBAQMyRr216kmxghw== + dependencies: + "@typescript-eslint/types" "4.14.1" + "@typescript-eslint/visitor-keys" "4.14.1" + "@typescript-eslint/scope-manager@4.14.2": version "4.14.2" resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.14.2.tgz#64cbc9ca64b60069aae0c060b2bf81163243b266" @@ -2136,16 +2203,34 @@ "@typescript-eslint/types" "4.14.2" "@typescript-eslint/visitor-keys" "4.14.2" +"@typescript-eslint/scope-manager@4.4.1": + version "4.4.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.4.1.tgz#d19447e60db2ce9c425898d62fa03b2cce8ea3f9" + integrity sha512-2oD/ZqD4Gj41UdFeWZxegH3cVEEH/Z6Bhr/XvwTtGv66737XkR4C9IqEkebCuqArqBJQSj4AgNHHiN1okzD/wQ== + dependencies: + "@typescript-eslint/types" "4.4.1" + "@typescript-eslint/visitor-keys" "4.4.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.14.1": + version "4.14.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.14.1.tgz#b3d2eb91dafd0fd8b3fce7c61512ac66bd0364aa" + integrity sha512-SkhzHdI/AllAgQSxXM89XwS1Tkic7csPdndUuTKabEwRcEfR8uQ/iPA3Dgio1rqsV3jtqZhY0QQni8rLswJM2w== + "@typescript-eslint/types@4.14.2": version "4.14.2" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.14.2.tgz#d96da62be22dc9dc6a06647f3633815350fb3174" integrity sha512-LltxawRW6wXy4Gck6ZKlBD05tCHQUj4KLn4iR69IyRiDHX3d3NCAhO+ix5OR2Q+q9bjCrHE/HKt+riZkd1At8Q== +"@typescript-eslint/types@4.4.1": + version "4.4.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.4.1.tgz#c507b35cf523bc7ba00aae5f75ee9b810cdabbc1" + integrity sha512-KNDfH2bCyax5db+KKIZT4rfA8rEk5N0EJ8P0T5AJjo5xrV26UAzaiqoJCxeaibqc0c/IvZxp7v2g3difn2Pn3w== + "@typescript-eslint/typescript-estree@3.10.1": version "3.10.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-3.10.1.tgz#fd0061cc38add4fad45136d654408569f365b853" @@ -2160,6 +2245,20 @@ semver "^7.3.2" tsutils "^3.17.1" +"@typescript-eslint/typescript-estree@4.14.1": + version "4.14.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.14.1.tgz#20d3b8c8e3cdc8f764bdd5e5b0606dd83da6075b" + integrity sha512-M8+7MbzKC1PvJIA8kR2sSBnex8bsR5auatLCnVlNTJczmJgqRn8M+sAlQfkEq7M4IY3WmaNJ+LJjPVRrREVSHQ== + dependencies: + "@typescript-eslint/types" "4.14.1" + "@typescript-eslint/visitor-keys" "4.14.1" + debug "^4.1.1" + globby "^11.0.1" + is-glob "^4.0.1" + lodash "^4.17.15" + semver "^7.3.2" + tsutils "^3.17.1" + "@typescript-eslint/typescript-estree@4.14.2": version "4.14.2" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.14.2.tgz#9c5ebd8cae4d7b014f890acd81e8e17f309c9df9" @@ -2174,6 +2273,20 @@ semver "^7.3.2" tsutils "^3.17.1" +"@typescript-eslint/typescript-estree@4.4.1": + version "4.4.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.4.1.tgz#598f6de488106c2587d47ca2462c60f6e2797cb8" + integrity sha512-wP/V7ScKzgSdtcY1a0pZYBoCxrCstLrgRQ2O9MmCUZDtmgxCO/TCqOTGRVwpP4/2hVfqMz/Vw1ZYrG8cVxvN3g== + dependencies: + "@typescript-eslint/types" "4.4.1" + "@typescript-eslint/visitor-keys" "4.4.1" + debug "^4.1.1" + globby "^11.0.1" + is-glob "^4.0.1" + lodash "^4.17.15" + semver "^7.3.2" + tsutils "^3.17.1" + "@typescript-eslint/visitor-keys@3.10.1": version "3.10.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-3.10.1.tgz#cd4274773e3eb63b2e870ac602274487ecd1e931" @@ -2181,6 +2294,14 @@ dependencies: eslint-visitor-keys "^1.1.0" +"@typescript-eslint/visitor-keys@4.14.1": + version "4.14.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.14.1.tgz#e93c2ff27f47ee477a929b970ca89d60a117da91" + integrity sha512-TAblbDXOI7bd0C/9PE1G+AFo7R5uc+ty1ArDoxmrC1ah61Hn6shURKy7gLdRb1qKJmjHkqu5Oq+e4Kt0jwf1IA== + dependencies: + "@typescript-eslint/types" "4.14.1" + eslint-visitor-keys "^2.0.0" + "@typescript-eslint/visitor-keys@4.14.2": version "4.14.2" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.14.2.tgz#997cbe2cb0690e1f384a833f64794e98727c70c6" @@ -2189,6 +2310,14 @@ "@typescript-eslint/types" "4.14.2" eslint-visitor-keys "^2.0.0" +"@typescript-eslint/visitor-keys@4.4.1": + version "4.4.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.4.1.tgz#1769dc7a9e2d7d2cfd3318b77ed8249187aed5c3" + integrity sha512-H2JMWhLaJNeaylSnMSQFEhT/S/FsJbebQALmoJxMPMxLtlVAMy2uJP/Z543n9IizhjRayLSqoInehCeNW9rWcw== + dependencies: + "@typescript-eslint/types" "4.4.1" + eslint-visitor-keys "^2.0.0" + "@webassemblyjs/ast@1.9.0": version "1.9.0" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964" @@ -3821,7 +3950,7 @@ concat-stream@^1.5.0: readable-stream "^2.2.2" typedarray "^0.0.6" -confusing-browser-globals@^1.0.10: +confusing-browser-globals@^1.0.10, confusing-browser-globals@^1.0.9: version "1.0.10" resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.10.tgz#30d1e7f3d1b882b25ec4933d1d1adac353d20a59" integrity sha512-gNld/3lySHwuhaVluJUKLePYirM3QNCKzVxqAdhJII9/WXKVX5PURzMVJspS1jTslSqjeuG4KMVTSouit5YPHA== @@ -4281,16 +4410,16 @@ cssstyle@^2.2.0: dependencies: cssom "~0.3.6" +csstype@3.0.6, csstype@^3.0.2: + version "3.0.6" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.6.tgz#865d0b5833d7d8d40f4e5b8a6d76aea3de4725ef" + integrity sha512-+ZAmfyWMT7TiIlzdqJgjMb7S4f1beorDbWbsocyK4RaiqA5RTX3K14bnBWmmA9QEM0gRdsjyyrEmcyga8Zsxmw== + csstype@^2.5.2: version "2.6.14" resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.14.tgz#004822a4050345b55ad4dcc00be1d9cf2f4296de" integrity sha512-2mSc+VEpGPblzAxyeR+vZhJKgYg0Og0nnRi7pmRXFYYxSfnOnW8A5wwQb4n4cE2nIOzqKOAzLCaEX6aBmNEv8A== -csstype@^3.0.2: - version "3.0.6" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.6.tgz#865d0b5833d7d8d40f4e5b8a6d76aea3de4725ef" - integrity sha512-+ZAmfyWMT7TiIlzdqJgjMb7S4f1beorDbWbsocyK4RaiqA5RTX3K14bnBWmmA9QEM0gRdsjyyrEmcyga8Zsxmw== - cyclist@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" @@ -4741,9 +4870,9 @@ ejs@^2.6.1: integrity sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA== electron-to-chromium@^1.3.564, electron-to-chromium@^1.3.649: - version "1.3.650" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.650.tgz#24e821fff2ed61fd71fee092f2a0631b3c0c22a6" - integrity sha512-j6pRuNylFBbroG6NB8Lw/Im9oDY74s2zWHBP5TmdYg73cBuL6cz//SMgolVa0gIJk/DSL+kO7baJ1DSXW1FUZg== + version "1.3.653" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.653.tgz#1d98400eba330538a7fe169808c6bf9d83c44450" + integrity sha512-LehOhcl74u9fkV9Un6WahJ+Xh+0FZLCCDnKYis1Olx1DX2ugRww5PJicE65OG8yznMj8EOQZRcz6FSV1xKxqsA== elliptic@^6.5.3: version "6.5.4" @@ -4951,6 +5080,47 @@ escodegen@^1.14.1: optionalDependencies: source-map "~0.6.1" +eslint-config-airbnb-base@14.2.0: + version "14.2.0" + resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.0.tgz#fe89c24b3f9dc8008c9c0d0d88c28f95ed65e9c4" + integrity sha512-Snswd5oC6nJaevs3nZoLSTvGJBvzTfnBqOIArkf3cbyTyq9UD79wOk8s+RiL6bhca0p/eRO6veczhf6A/7Jy8Q== + dependencies: + confusing-browser-globals "^1.0.9" + object.assign "^4.1.0" + object.entries "^1.1.2" + +eslint-config-airbnb-base@^14.2.0: + version "14.2.1" + resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.1.tgz#8a2eb38455dc5a312550193b319cdaeef042cd1e" + integrity sha512-GOrQyDtVEc1Xy20U7vsB2yAoB4nBlfH5HZJeatRXHleO+OS5Ot+MWij4Dpltw4/DyIkqUfqz1epfhVR5XWWQPA== + dependencies: + confusing-browser-globals "^1.0.10" + object.assign "^4.1.2" + object.entries "^1.1.2" + +eslint-config-airbnb-typescript@12.0.0: + version "12.0.0" + resolved "https://registry.yarnpkg.com/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-12.0.0.tgz#4bb6b4b72b1cfc45ef1fa0607735679ceb9a3814" + integrity sha512-TUCVru1Z09eKnVAX5i3XoNzjcCOU3nDQz2/jQGkg1jVYm+25fKClveziSl16celfCq+npU0MBPW/ZnXdGFZ9lw== + dependencies: + "@typescript-eslint/parser" "4.4.1" + eslint-config-airbnb "18.2.0" + eslint-config-airbnb-base "14.2.0" + +eslint-config-airbnb@18.2.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/eslint-config-airbnb/-/eslint-config-airbnb-18.2.0.tgz#8a82168713effce8fc08e10896a63f1235499dcd" + integrity sha512-Fz4JIUKkrhO0du2cg5opdyPKQXOI2MvF8KUvN2710nJMT6jaRUpRE2swrJftAjVGL7T1otLM5ieo5RqS1v9Udg== + dependencies: + eslint-config-airbnb-base "^14.2.0" + object.assign "^4.1.0" + object.entries "^1.1.2" + +eslint-config-prettier@7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-7.2.0.tgz#f4a4bd2832e810e8cc7c1411ec85b3e85c0c53f9" + integrity sha512-rV4Qu0C3nfJKPOAhFujFxB7RMP+URFyQqqOZW9DMRD7ZDTFyjaIlETU3xzHELt++4ugC0+Jm084HQYkkJe+Ivg== + eslint-config-react-app@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/eslint-config-react-app/-/eslint-config-react-app-6.0.0.tgz#ccff9fc8e36b322902844cbd79197982be355a0e" @@ -4982,7 +5152,7 @@ eslint-plugin-flowtype@^5.2.0: lodash "^4.17.15" string-natural-compare "^3.0.1" -eslint-plugin-import@^2.22.1: +eslint-plugin-import@2.22.1, eslint-plugin-import@^2.22.1: version "2.22.1" resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz#0896c7e6a0cf44109a2d97b95903c2bb689d7702" integrity sha512-8K7JjINHOpH64ozkAhpT3sd+FswIZTfMZTjdx052pnWrgRCVfp8op9tbjpAk3DdUeI/Ba4C8OjdC0r90erHEOw== @@ -5008,7 +5178,7 @@ eslint-plugin-jest@^24.1.0: dependencies: "@typescript-eslint/experimental-utils" "^4.0.1" -eslint-plugin-jsx-a11y@^6.3.1: +eslint-plugin-jsx-a11y@6.4.1, eslint-plugin-jsx-a11y@^6.3.1: version "6.4.1" resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.4.1.tgz#a2d84caa49756942f42f1ffab9002436391718fd" integrity sha512-0rGPJBbwHoGNPU73/QCLP/vveMlM1b1Z9PponxO87jfr6tuH5ligXbDT6nHSSzBC8ovX2Z+BQu7Bk5D/Xgq9zg== @@ -5025,12 +5195,19 @@ eslint-plugin-jsx-a11y@^6.3.1: jsx-ast-utils "^3.1.0" language-tags "^1.0.5" -eslint-plugin-react-hooks@^4.2.0: +eslint-plugin-prettier@3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.3.1.tgz#7079cfa2497078905011e6f82e8dd8453d1371b7" + integrity sha512-Rq3jkcFY8RYeQLgk2cCwuc0P7SEFwDravPhsJZOQ5N4YI4DSg50NyqJ/9gdZHzQlHf8MvafSesbNJCcP/FF6pQ== + dependencies: + prettier-linter-helpers "^1.0.0" + +eslint-plugin-react-hooks@4.2.0, eslint-plugin-react-hooks@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.2.0.tgz#8c229c268d468956334c943bb45fc860280f5556" integrity sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ== -eslint-plugin-react@^7.21.5: +eslint-plugin-react@7.22.0, eslint-plugin-react@^7.21.5: version "7.22.0" resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.22.0.tgz#3d1c542d1d3169c45421c1215d9470e341707269" integrity sha512-p30tuX3VS+NWv9nQot9xIGAHBXR0+xJVaZriEsHoJrASGCJZDJ8JLNM0YqKqI0AKm6Uxaa1VUHoNEibxRCMQHA== @@ -5098,7 +5275,7 @@ eslint-webpack-plugin@^2.1.0: micromatch "^4.0.2" schema-utils "^3.0.0" -eslint@^7.11.0: +eslint@7.19.0, eslint@^7.11.0: version "7.19.0" resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.19.0.tgz#6719621b196b5fad72e43387981314e5d0dc3f41" integrity sha512-CGlMgJY56JZ9ZSYhJuhow61lMPPjUzWmChFya71Z/jilVos7mR/jPgaEfVGgMBY5DshbKdG8Ezb8FDCHcoMEMg== @@ -5425,6 +5602,11 @@ fast-deep-equal@^3.1.1: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== +fast-diff@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" + integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== + fast-glob@^3.1.1: version "3.2.5" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.5.tgz#7939af2a656de79a4f1901903ee8adcaa7cb9661" @@ -5807,9 +5989,9 @@ get-caller-file@^2.0.1: integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== get-intrinsic@^1.0.1, get-intrinsic@^1.0.2, get-intrinsic@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.0.tgz#892e62931e6938c8a23ea5aaebcfb67bd97da97e" - integrity sha512-M11rgtQp5GZMZzDL7jLTNxbDfurpzuau5uqRWDPvlHjfvg3TdScAZo96GLvhMjImrmR8uAt0FS2RLoMrfWGKlg== + version "1.1.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" + integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== dependencies: function-bind "^1.1.1" has "^1.0.3" @@ -9900,6 +10082,18 @@ prepend-http@^1.0.0: resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= +prettier-linter-helpers@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" + integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== + dependencies: + fast-diff "^1.1.2" + +prettier@2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.2.1.tgz#795a1a78dd52f073da0cd42b21f9c91381923ff5" + integrity sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q== + pretty-bytes@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.5.0.tgz#0cecda50a74a941589498011cf23275aa82b339e" @@ -10197,9 +10391,9 @@ react-chartjs-2@2.10.0: prop-types "^15.7.2" react-dev-utils@^11.0.1: - version "11.0.1" - resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-11.0.1.tgz#30106c2055acfd6b047d2dc478a85c356e66fe45" - integrity sha512-rlgpCupaW6qQqvu0hvv2FDv40QG427fjghV56XyPcP5aKtOAPzNAhQ7bHqk1YdS2vpW1W7aSV3JobedxuPlBAA== + version "11.0.2" + resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-11.0.2.tgz#98aed16ef50f808ee17b32def75eb15f89655802" + integrity sha512-xG7GlMoYkrgc2M1kDCHKRywXMDbFnjOB+/VzpytQyYBusEzR8NlGTMmUbvN86k94yyKu5XReHB8eZC2JZrNchQ== dependencies: "@babel/code-frame" "7.10.4" address "1.1.2" @@ -10220,7 +10414,7 @@ react-dev-utils@^11.0.1: open "^7.0.2" pkg-up "3.1.0" prompts "2.4.0" - react-error-overlay "^6.0.8" + react-error-overlay "^6.0.9" recursive-readdir "2.2.2" shell-quote "1.7.2" strip-ansi "6.0.0" @@ -10236,10 +10430,10 @@ react-dom@16.13.1: prop-types "^15.6.2" scheduler "^0.19.1" -react-error-overlay@^6.0.8: - version "6.0.8" - resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.8.tgz#474ed11d04fc6bda3af643447d85e9127ed6b5de" - integrity sha512-HvPuUQnLp5H7TouGq3kzBeioJmXms1wHy9EGjz2OURWBp4qZO6AfGEcnxts1D/CbwPLRAgTMPCEgYhA3sEM4vw== +react-error-overlay@^6.0.9: + version "6.0.9" + resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.9.tgz#3c743010c9359608c375ecd6bc76f35d93995b0a" + integrity sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew== react-is@^16.12.0, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.0, react-is@^16.8.1, react-is@^16.8.4: version "16.13.1"