diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..77f878d --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +src/reportWebVitals.jsx diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..067977b --- /dev/null +++ b/.eslintrc @@ -0,0 +1,11 @@ +"extends": "airbnb" +"env": { + "browser": true, + "jest": true, +} +"rules": { + "allowShortCircuit": 0, + "allowTernary": 0, + "no-unused-expressions": "off", + "no-mixed-operators": "off" +} diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..b7fd28b --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,23 @@ +name: Deploy + +on: + push: + branches: + - develop + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v1 + - name: git config + run: | + git config user.name github-pages-deploy-action + git config user.email github-pages-deploy-action@@users.noreply.github.com + git remote set-url origin https://${{github.actor}}:${{github.token}}@github.com/${{github.repository}}.git + - run: yarn install + - run: yarn build + env: + REACT_APP_GITHUB_PAT: ${{ secrets.REACT_APP_GITHUB_PAT }} + - run: yarn deploy diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..9994603 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,19 @@ +name: Tests + +on: [push] + +jobs: + build: + + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v1 + - run: yarn install + - run: yarn test + env: + REACT_APP_GITHUB_PAT: ${{ secrets.REACT_APP_GITHUB_PAT }} + - run: yarn lint + - uses: coverallsapp/github-action@v1.1.2 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index 4d29575..726bc94 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. +.env # dependencies /node_modules @@ -21,3 +21,6 @@ npm-debug.log* yarn-debug.log* yarn-error.log* + +# Optional eslint cache +.eslintcache diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..28b6775 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,4 @@ +# Change Log + +## [2020.12.10] + - Initial UI release diff --git a/README.md b/README.md index 02aac3f..379d3a1 100644 --- a/README.md +++ b/README.md @@ -1,70 +1,30 @@ -# Getting Started with Create React App +# GitPop3 -This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). +[![Tests](https://github.com/AndreMiras/gitpop3/workflows/Tests/badge.svg?branch=develop)](https://github.com/AndreMiras/gitpop3/actions?query=workflow%3ATests) +[![Coverage Status](https://coveralls.io/repos/github/AndreMiras/gitpop3/badge.svg?branch=develop)](https://coveralls.io/github/AndreMiras/gitpop3?branch=develop) +[![Deploy](https://github.com/AndreMiras/gitpop3/workflows/Deploy/badge.svg?branch=develop)](https://github.com/AndreMiras/gitpop3/actions?query=workflow%3ADeploy) -## Available Scripts +Find the most popular fork on GitHub. -In the project directory, you can run: + -### `yarn start` +This is a rewrite of [GitPop2](https://github.com/AndreMiras/gitpop2) using only frontend tech. -Runs the app in the development mode.\ -Open [http://localhost:3000](http://localhost:3000) to view it in the browser. +## Run +```sh +yarn start +``` -The page will reload if you make edits.\ -You will also see any lint errors in the console. +## Test +```sh +yarn lint +yarn test +``` -### `yarn test` - -Launches the test runner in the interactive watch mode.\ -See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. - -### `yarn build` - -Builds the app for production to the `build` folder.\ -It correctly bundles React in production mode and optimizes the build for the best performance. - -The build is minified and the filenames include the hashes.\ -Your app is ready to be deployed! - -See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. - -### `yarn eject` - -**Note: this is a one-way operation. Once you `eject`, you can’t go back!** - -If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. - -Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. - -You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. - -## Learn More - -You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). - -To learn React, check out the [React documentation](https://reactjs.org/). - -### Code Splitting - -This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting) - -### Analyzing the Bundle Size - -This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size) - -### Making a Progressive Web App - -This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app) - -### Advanced Configuration - -This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration) - -### Deployment - -This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment) - -### `yarn build` fails to minify - -This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify) +## Deployment +The app can be deployed on GitHub pages when releasing via: +```sh +yarn deploy +``` +Note a [Personal Access Token](https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-github/creating-a-personal-access-token) should be generated and set to its base64 form to the `REACT_APP_GITHUB_PAT` environment variable. +This is required for [Authenticating with GraphQL](https://docs.github.com/en/free-pro-team@latest/graphql/guides/forming-calls-with-graphql#authenticating-with-graphql). diff --git a/package.json b/package.json index 4e3e3aa..09d582d 100644 --- a/package.json +++ b/package.json @@ -1,21 +1,37 @@ { "name": "gitpop3", - "version": "0.1.0", + "homepage": "https://andremiras.github.io/gitpop3/", + "version": "2020.12.10", "private": true, "dependencies": { + "@apollo/client": "^3.2.7", + "@fortawesome/fontawesome-free": "^5.15.1", + "@fortawesome/fontawesome-svg-core": "^1.2.32", + "@fortawesome/free-brands-svg-icons": "^5.15.1", + "@fortawesome/free-solid-svg-icons": "^5.15.1", + "@fortawesome/react-fontawesome": "^0.1.12", "@testing-library/jest-dom": "^5.11.4", "@testing-library/react": "^11.1.0", "@testing-library/user-event": "^12.1.10", + "bootstrap": "^4.5.3", + "font-awesome": "^4.7.0", + "graphql": "^15.4.0", + "prop-types": "^15.7.2", "react": "^17.0.1", + "react-bootstrap": "^1.4.0", "react-dom": "^17.0.1", + "react-js-pagination": "^3.0.3", "react-scripts": "4.0.1", "web-vitals": "^0.2.4" }, "scripts": { "start": "react-scripts start", "build": "react-scripts build", - "test": "react-scripts test", - "eject": "react-scripts eject" + "test": "react-scripts test --coverage", + "eject": "react-scripts eject", + "lint": "eslint -c .eslintrc 'src/**/*.{js,jsx}'", + "format": "eslint -c .eslintrc 'src/**/*.{js,jsx}' --fix", + "deploy": "gh-pages -d build" }, "eslintConfig": { "extends": [ @@ -23,6 +39,12 @@ "react-app/jest" ] }, + "jest": { + "collectCoverageFrom": [ + "src/**/*.{js,jsx}", + "!src/reportWebVitals.jsx" + ] + }, "browserslist": { "production": [ ">0.2%", @@ -34,5 +56,12 @@ "last 1 firefox version", "last 1 safari version" ] + }, + "devDependencies": { + "coveralls": "^3.1.0", + "eslint-config-airbnb": "^18.2.1", + "gh-pages": "^3.1.0", + "moment": "^2.29.1", + "react-test-renderer": "^17.0.1" } } diff --git a/public/favicon.ico b/public/favicon.ico index a11777c..25fe4c5 100644 Binary files a/public/favicon.ico and b/public/favicon.ico differ diff --git a/public/index.html b/public/index.html index aa069f2..ee78a3b 100644 --- a/public/index.html +++ b/public/index.html @@ -7,7 +7,7 @@ - React App + GitPop3: Find the most popular fork on GitHub diff --git a/src/App.css b/src/App.css index 74b5e05..e69de29 100644 --- a/src/App.css +++ b/src/App.css @@ -1,38 +0,0 @@ -.App { - text-align: center; -} - -.App-logo { - height: 40vmin; - pointer-events: none; -} - -@media (prefers-reduced-motion: no-preference) { - .App-logo { - animation: App-logo-spin infinite 20s linear; - } -} - -.App-header { - background-color: #282c34; - min-height: 100vh; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - font-size: calc(10px + 2vmin); - color: white; -} - -.App-link { - color: #61dafb; -} - -@keyframes App-logo-spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } -} diff --git a/src/App.js b/src/App.js deleted file mode 100644 index 3784575..0000000 --- a/src/App.js +++ /dev/null @@ -1,25 +0,0 @@ -import logo from './logo.svg'; -import './App.css'; - -function App() { - return ( -
-
- logo -

- Edit src/App.js and save to reload. -

- - Learn React - -
-
- ); -} - -export default App; diff --git a/src/App.jsx b/src/App.jsx new file mode 100644 index 0000000..581e223 --- /dev/null +++ b/src/App.jsx @@ -0,0 +1,23 @@ +import React from 'react'; +import './App.css'; +import 'bootstrap/dist/css/bootstrap.min.css'; +import { library } from '@fortawesome/fontawesome-svg-core'; +import { fab } from '@fortawesome/free-brands-svg-icons'; +import { fas } from '@fortawesome/free-solid-svg-icons'; +import Container from './components/Container'; +import Footer from './components/Footer'; +import Navigation from './components/Navigation'; + +library.add(fab, fas); + +function App() { + return ( +
+ + +
+
+ ); +} + +export default App; diff --git a/src/App.test.js b/src/App.test.jsx similarity index 57% rename from src/App.test.js rename to src/App.test.jsx index 1f03afe..54b17d5 100644 --- a/src/App.test.js +++ b/src/App.test.jsx @@ -1,8 +1,9 @@ +import React from 'react'; import { render, screen } from '@testing-library/react'; import App from './App'; -test('renders learn react link', () => { +test('renders title', () => { render(); - const linkElement = screen.getByText(/learn react/i); + const linkElement = screen.getByText(/GitPop3/); expect(linkElement).toBeInTheDocument(); }); diff --git a/src/components/Container.jsx b/src/components/Container.jsx new file mode 100644 index 0000000..e2f579b --- /dev/null +++ b/src/components/Container.jsx @@ -0,0 +1,39 @@ +import React, { useState } from 'react'; +import { Container as ReactContainer } from 'react-bootstrap'; +import PopForm from './PopForm'; +import ResultTable from './ResultTable'; +import searchPopularForks from '../utils/search'; + +const Container = () => { + const [forks, setForks] = useState(); + const [activePage, setActivePage] = useState(1); + const [loading, setLoading] = useState(false); + const onResult = (result) => { + setForks(result.data.repository.forks.nodes); + setLoading(false); + }; + const onSubmit = (url) => { + setLoading(true); + searchPopularForks(url, onResult); + }; + const resultTable = ( + forks + ? ( + + ) + : null + ); + return ( + + + {resultTable} + + ); +}; + +export default Container; diff --git a/src/components/Container.test.jsx b/src/components/Container.test.jsx new file mode 100644 index 0000000..e215d47 --- /dev/null +++ b/src/components/Container.test.jsx @@ -0,0 +1,57 @@ +import React from 'react'; +import { fireEvent, render, screen } from '@testing-library/react'; +import renderer from 'react-test-renderer'; +import { library } from '@fortawesome/fontawesome-svg-core'; +import { fab } from '@fortawesome/free-brands-svg-icons'; +import { fas } from '@fortawesome/free-solid-svg-icons'; +import searchPopularForks from '../utils/search'; +import Container from './Container'; + +library.add(fab, fas); +jest.mock('../utils/search'); + +const forks = [ + { + nameWithOwner: 'django-nonrel/django', + stargazerCount: 214, + forkCount: 84, + pushedAt: '2020-08-29T14:23:26Z', + object: { + history: { + totalCount: 13990, + }, + }, + }, +]; + +const searchResult = { + data: { + repository: { + forks: { + nodes: forks, + }, + }, + }, +}; + +test('renders', () => { + const tree = renderer.create( + , + ).toJSON(); + expect(tree).toMatchSnapshot(); +}); + +test('search forks', (done) => { + render(); + const searchInput = screen.getByPlaceholderText(/github.com/); + const submitButton = screen.getByRole('button', { type: 'submit' }); + const forkId = 'django-nonrel/django'; + searchPopularForks.mockImplementationOnce((url, onResult) => { + onResult(searchResult); + done(); + }); + expect(screen.queryByText(forkId)).toBeNull(); + fireEvent.change(searchInput, { target: { value: 'https://github.com/django/django' } }); + fireEvent.click(submitButton); + expect(screen.queryByText(forkId)).toBeInTheDocument(); +}); diff --git a/src/components/Footer.jsx b/src/components/Footer.jsx new file mode 100644 index 0000000..2b2bf9c --- /dev/null +++ b/src/components/Footer.jsx @@ -0,0 +1,16 @@ +import React from 'react'; +import { Container } from 'react-bootstrap'; +import { version } from '../../package.json'; + +const Footer = () => ( +
+ + + Copyright © Andre Miras 2020 - gitpop3 v + {version} + + +
+); + +export default Footer; diff --git a/src/components/ForkLine.jsx b/src/components/ForkLine.jsx new file mode 100644 index 0000000..e18caa7 --- /dev/null +++ b/src/components/ForkLine.jsx @@ -0,0 +1,29 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import timeSince from '../utils/time'; +import RepoLink from './RepoLink'; + +const ForkLine = ({ info }) => ( + + + {info.stargazerCount} + {info.forkCount} + {info.object.history.totalCount} + {timeSince(Date.parse(info.pushedAt))} + +); +ForkLine.propTypes = { + info: PropTypes.shape({ + nameWithOwner: PropTypes.string.isRequired, + stargazerCount: PropTypes.number.isRequired, + forkCount: PropTypes.number.isRequired, + pushedAt: PropTypes.string.isRequired, + object: PropTypes.shape({ + history: PropTypes.shape({ + totalCount: PropTypes.number.isRequired, + }).isRequired, + }).isRequired, + }).isRequired, +}; + +export default ForkLine; diff --git a/src/components/ForkLine.test.jsx b/src/components/ForkLine.test.jsx new file mode 100644 index 0000000..3c0aeb6 --- /dev/null +++ b/src/components/ForkLine.test.jsx @@ -0,0 +1,21 @@ +import React from 'react'; +import renderer from 'react-test-renderer'; +import ForkLine from './ForkLine'; + +test('renders', () => { + const info = { + nameWithOwner: 'django/django', + stargazerCount: 123, + forkCount: 321, + pushedAt: '2020-08-29T14:23:26Z', + object: { + history: { + totalCount: 1234, + }, + }, + }; + const tree = renderer.create( + , + ).toJSON(); + expect(tree).toMatchSnapshot(); +}); diff --git a/src/components/Navigation.jsx b/src/components/Navigation.jsx new file mode 100644 index 0000000..a5ce14c --- /dev/null +++ b/src/components/Navigation.jsx @@ -0,0 +1,32 @@ +import React from 'react'; +import { Container, Nav, Navbar } from 'react-bootstrap'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; + +const Navigation = () => ( + + + + + {' '} + GitPop3 + + + + + + + +); + +export default Navigation; diff --git a/src/components/PopForm.jsx b/src/components/PopForm.jsx new file mode 100644 index 0000000..0d7b094 --- /dev/null +++ b/src/components/PopForm.jsx @@ -0,0 +1,48 @@ +import React, { useState } from 'react'; +import PropTypes from 'prop-types'; +import { + Button, Form, FormControl, InputGroup, +} from 'react-bootstrap'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { urlMatch } from '../utils/validators'; + +const SearchIcon = ({ loading }) => ( + +); +SearchIcon.propTypes = { + loading: PropTypes.bool.isRequired, +}; + +const PopForm = ({ onSubmit, loading }) => { + const [url, setUrl] = useState(); + const handleSubmit = (e) => { + e.preventDefault(); + if (urlMatch(url) === null) { + e.stopPropagation(); + } else { + onSubmit(url); + } + }; + return ( +
+ + setUrl(e.target.value)} + isInvalid={urlMatch(url) === null} + /> + + + + +
+ ); +}; +PopForm.propTypes = { + onSubmit: PropTypes.func.isRequired, + loading: PropTypes.bool.isRequired, +}; + +export default PopForm; diff --git a/src/components/PopForm.test.jsx b/src/components/PopForm.test.jsx new file mode 100644 index 0000000..c52a7e7 --- /dev/null +++ b/src/components/PopForm.test.jsx @@ -0,0 +1,50 @@ +import React from 'react'; +import renderer from 'react-test-renderer'; +import { fireEvent, render, screen } from '@testing-library/react'; +import { library } from '@fortawesome/fontawesome-svg-core'; +import { fas } from '@fortawesome/free-solid-svg-icons'; +import PopForm from './PopForm'; + +library.add(fas); + +test('renders', () => { + const onSubmit = () => ({}); + const tree = renderer.create( + , + ).toJSON(); + expect(tree).toMatchSnapshot(); +}); + +describe.each([ + true, + false, +])("loading='%s'", (loading) => { + test('renders', () => { + const onSubmit = () => ({}); + const tree = renderer.create( + , + ).toJSON(); + expect(tree).toMatchSnapshot(); + }); +}); + +test('submit', () => { + const onSubmit = jest.fn(); + render(); + const searchInput = screen.getByPlaceholderText(/github.com/); + const expectedUrl = 'https://github.com/django/django'; + fireEvent.change(searchInput, { target: { value: expectedUrl } }); + const submitButton = screen.getByRole('button', { type: 'submit' }); + // mouse click + fireEvent.click(submitButton); + expect(onSubmit).toHaveBeenNthCalledWith(1, expectedUrl); + // invalid URL should not trigger the submit callback + const invalidUrl = 'https://github.com/invalid-url'; + fireEvent.change(searchInput, { target: { value: invalidUrl } }); + fireEvent.click(submitButton); + expect(onSubmit).toHaveBeenNthCalledWith(1, expectedUrl); + // submit (keyboard Enter) should also be mapped + fireEvent.change(searchInput, { target: { value: expectedUrl } }); + fireEvent.submit(searchInput); + expect(onSubmit).toHaveBeenNthCalledWith(2, expectedUrl); +}); diff --git a/src/components/RepoLink.jsx b/src/components/RepoLink.jsx new file mode 100644 index 0000000..40ec6d2 --- /dev/null +++ b/src/components/RepoLink.jsx @@ -0,0 +1,13 @@ +import React from 'react'; +import PropTypes from 'prop-types'; + +const RepoLink = ({ nameWithOwner }) => ( + + {nameWithOwner} + +); +RepoLink.propTypes = { + nameWithOwner: PropTypes.string.isRequired, +}; + +export default RepoLink; diff --git a/src/components/RepoLink.test.jsx b/src/components/RepoLink.test.jsx new file mode 100644 index 0000000..5c39428 --- /dev/null +++ b/src/components/RepoLink.test.jsx @@ -0,0 +1,10 @@ +import React from 'react'; +import renderer from 'react-test-renderer'; +import RepoLink from './RepoLink'; + +test('renders', () => { + const tree = renderer.create( + , + ).toJSON(); + expect(tree).toMatchSnapshot(); +}); diff --git a/src/components/ResultTable.jsx b/src/components/ResultTable.jsx new file mode 100644 index 0000000..dfa6891 --- /dev/null +++ b/src/components/ResultTable.jsx @@ -0,0 +1,76 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { Table } from 'react-bootstrap'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import Pagination from 'react-js-pagination'; +import ForkLine from './ForkLine'; + +const paginatedForks = (forks, activePage, itemsCountPerPage) => ( + forks.slice((activePage - 1) * itemsCountPerPage, activePage * itemsCountPerPage) +); + +const ResultTable = ({ + forks, activePage, itemsCountPerPage, onPageChange, +}) => ( + <> + + + + + + + + + + + + { + paginatedForks( + forks, + activePage, + itemsCountPerPage, + ).map( + (fork) => , + ) + } + +
+ + {' '} + Repo + + + {' '} + Stars + + + {' '} + Forks + + + {' '} + Commits + + + {' '} + Modified +
+ + +); +ResultTable.propTypes = { + forks: PropTypes.arrayOf(ForkLine.propTypes.info).isRequired, + activePage: PropTypes.number.isRequired, + itemsCountPerPage: PropTypes.number.isRequired, + onPageChange: PropTypes.func.isRequired, +}; + +export default ResultTable; diff --git a/src/components/ResultTable.test.jsx b/src/components/ResultTable.test.jsx new file mode 100644 index 0000000..2d83db2 --- /dev/null +++ b/src/components/ResultTable.test.jsx @@ -0,0 +1,50 @@ +import React from 'react'; +import renderer from 'react-test-renderer'; +import { library } from '@fortawesome/fontawesome-svg-core'; +import { fab } from '@fortawesome/free-brands-svg-icons'; +import { fas } from '@fortawesome/free-solid-svg-icons'; +import ResultTable from './ResultTable'; + +library.add(fab, fas); + +test('renders', () => { + const forks = [ + { + nameWithOwner: 'django-nonrel/django', + stargazerCount: 214, + forkCount: 84, + pushedAt: '2020-08-29T14:23:26Z', + object: { + history: { + totalCount: 13990, + }, + }, + }, + { + nameWithOwner: 'django/django', + stargazerCount: 26, + forkCount: 2, + pushedAt: '2020-02-17:11:12Z', + object: { + history: { + totalCount: 26823, + }, + }, + }, + { + nameWithOwner: 'FlipperPA/django-mssql-backend', + stargazerCount: 18, + forkCount: 2, + pushedAt: '2020-01-13:11:12Z', + object: { + history: { + totalCount: 28017, + }, + }, + }, + ]; + const tree = renderer.create( + null} />, + ).toJSON(); + expect(tree).toMatchSnapshot(); +}); diff --git a/src/components/__snapshots__/Container.test.jsx.snap b/src/components/__snapshots__/Container.test.jsx.snap new file mode 100644 index 0000000..d8f28fe --- /dev/null +++ b/src/components/__snapshots__/Container.test.jsx.snap @@ -0,0 +1,50 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`renders 1`] = ` +
+
+
+ +
+ +
+
+
+
+`; diff --git a/src/components/__snapshots__/ForkLine.test.jsx.snap b/src/components/__snapshots__/ForkLine.test.jsx.snap new file mode 100644 index 0000000..6fb3e76 --- /dev/null +++ b/src/components/__snapshots__/ForkLine.test.jsx.snap @@ -0,0 +1,25 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`renders 1`] = ` + + + + django/django + + + + 123 + + + 321 + + + 1234 + + + 3 months ago + + +`; diff --git a/src/components/__snapshots__/PopForm.test.jsx.snap b/src/components/__snapshots__/PopForm.test.jsx.snap new file mode 100644 index 0000000..6627d7c --- /dev/null +++ b/src/components/__snapshots__/PopForm.test.jsx.snap @@ -0,0 +1,136 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`loading='false' renders 1`] = ` +
+
+ +
+ +
+
+
+`; + +exports[`loading='true' renders 1`] = ` +
+
+ +
+ +
+
+
+`; + +exports[`renders 1`] = ` +
+
+ +
+ +
+
+
+`; diff --git a/src/components/__snapshots__/RepoLink.test.jsx.snap b/src/components/__snapshots__/RepoLink.test.jsx.snap new file mode 100644 index 0000000..621acab --- /dev/null +++ b/src/components/__snapshots__/RepoLink.test.jsx.snap @@ -0,0 +1,9 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`renders 1`] = ` + + django/Django + +`; diff --git a/src/components/__snapshots__/ResultTable.test.jsx.snap b/src/components/__snapshots__/ResultTable.test.jsx.snap new file mode 100644 index 0000000..1d36c16 --- /dev/null +++ b/src/components/__snapshots__/ResultTable.test.jsx.snap @@ -0,0 +1,239 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`renders 1`] = ` +Array [ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + Repo + + + + Stars + + + + Forks + + + + Commits + + + + Modified +
+ + django-nonrel/django + + + 214 + + 84 + + 13990 + + 3 months ago +
+ + django/django + + + 26 + + 2 + + 26823 + + 9 months ago +
, + , +] +`; diff --git a/src/index.css b/src/index.css index ec2585e..61258ba 100644 --- a/src/index.css +++ b/src/index.css @@ -1,13 +1,18 @@ +html { + position: relative; + min-height: 100%; +} + body { - margin: 0; - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', - 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', - sans-serif; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; + margin-bottom: 70px!important; } -code { - font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', - monospace; +.footer { + position: absolute; + bottom: 0; + width: 100%; + height: 60px; + line-height: 60px; + background-color: #f5f5f5; + display: block; } diff --git a/src/index.js b/src/index.jsx similarity index 78% rename from src/index.js rename to src/index.jsx index ef2edf8..06c68c5 100644 --- a/src/index.js +++ b/src/index.jsx @@ -2,16 +2,16 @@ import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; import App from './App'; -import reportWebVitals from './reportWebVitals'; +// import reportWebVitals from './reportWebVitals'; ReactDOM.render( , - document.getElementById('root') + document.getElementById('root'), ); // If you want to start measuring performance in your app, pass a function // to log results (for example: reportWebVitals(console.log)) // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals -reportWebVitals(); +// reportWebVitals(); diff --git a/src/index.test.jsx b/src/index.test.jsx new file mode 100644 index 0000000..95ab86a --- /dev/null +++ b/src/index.test.jsx @@ -0,0 +1,20 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import App from './App'; + +jest.mock('react-dom', () => ({ render: jest.fn() })); + +describe('Application root', () => { + it('renders', () => { + const div = document.createElement('div'); + div.id = 'root'; + document.body.appendChild(div); + require('./index.jsx'); // eslint-disable-line global-require + expect(ReactDOM.render).toHaveBeenCalledWith( + + + , + div, + ); + }); +}); diff --git a/src/reportWebVitals.js b/src/reportWebVitals.jsx similarity index 100% rename from src/reportWebVitals.js rename to src/reportWebVitals.jsx diff --git a/src/utils/graphql.js b/src/utils/graphql.js new file mode 100644 index 0000000..15004b4 --- /dev/null +++ b/src/utils/graphql.js @@ -0,0 +1,60 @@ +import assert from 'assert'; +import { + gql, ApolloClient, createHttpLink, InMemoryCache, +} from '@apollo/client'; +import { setContext } from '@apollo/client/link/context'; + +const endpoint = 'https://api.github.com/graphql'; + +const httpLink = createHttpLink({ + uri: endpoint, +}); + +/** + * Base64 to trick GitHub hooks so the token doesn't seem leaded in the commit. + * Note this token will be accessible from the frontend hence should be very restricted. + * Only the `public_repo` scope is required. + */ +const token = process.env.REACT_APP_GITHUB_PAT ? atob(process.env.REACT_APP_GITHUB_PAT) : null; +assert( // eslint-disable-line no-console + token, 'REACT_APP_GITHUB_PAT environment variable must be set', +); + +const authLink = setContext((_, { headers }) => ({ + headers: { + ...headers, + authorization: `Bearer ${token}`, + }, +})); + +const client = new ApolloClient({ + link: authLink.concat(httpLink), + cache: new InMemoryCache(), +}); + +const GET_FORKS_QUERY = gql` + query Forks($owner: String! $name: String!) { + repository(owner: $owner, name: $name) { + forks(first: 100, orderBy: {field: STARGAZERS, direction: DESC}) { + nodes { + nameWithOwner + stargazerCount + forkCount + pushedAt + object(expression: "master") { + ... on Commit { + history { + totalCount + } + } + } + } + } + } + } +`; + +export { + client, + GET_FORKS_QUERY, +}; diff --git a/src/utils/graphql.test.js b/src/utils/graphql.test.js new file mode 100644 index 0000000..a59146b --- /dev/null +++ b/src/utils/graphql.test.js @@ -0,0 +1,25 @@ +describe('client', () => { + const OLD_ENV = process.env; + + beforeEach(() => { + jest.resetModules(); // most important - it clears the cache + process.env = { ...OLD_ENV }; // make a copy + }); + + afterAll(() => { + process.env = OLD_ENV; // restore old env + }); + + it('REACT_APP_GITHUB_PAT is set OK by default', () => { + const { client } = require('./graphql.js'); // eslint-disable-line global-require + // simply check the client got initialised OK + expect(client.version).toEqual('local'); + }); + + it('handles REACT_APP_GITHUB_PAT environment variable', () => { + delete process.env.REACT_APP_GITHUB_PAT; + expect(() => { + require('./graphql.js'); // eslint-disable-line global-require + }).toThrow('REACT_APP_GITHUB_PAT environment variable must be set'); + }); +}); diff --git a/src/utils/search.js b/src/utils/search.js new file mode 100644 index 0000000..620c50a --- /dev/null +++ b/src/utils/search.js @@ -0,0 +1,14 @@ +import { client, GET_FORKS_QUERY } from './graphql'; +import { splitUrl } from './validators'; + +const searchPopularForks = (url, onResult) => { + const [owner, name] = splitUrl(url); + client.query({ + query: GET_FORKS_QUERY, + variables: { owner, name }, + }).then( + (result) => onResult(result), + ); +}; + +export default searchPopularForks; diff --git a/src/utils/search.test.js b/src/utils/search.test.js new file mode 100644 index 0000000..312ad2f --- /dev/null +++ b/src/utils/search.test.js @@ -0,0 +1,28 @@ +import searchPopularForks from './search'; +import { client } from './graphql'; + +test('basic case', (done) => { + const url = 'https://github.com/django/django'; + const expected = { + data: { + repository: { + forks: { + nodes: [], + }, + }, + }, + }; + const onResult = (result) => { + expect(result).toEqual(expected); + done(); + }; + const querySpy = jest.spyOn(client, 'query').mockReturnValue(Promise.resolve(expected)); + expect( + searchPopularForks( + url, onResult, + ), + ); + expect(querySpy).toHaveBeenNthCalledWith( + 1, { query: expect.any(Object), variables: { owner: 'django', name: 'django' } }, + ); +}); diff --git a/src/utils/time.js b/src/utils/time.js new file mode 100644 index 0000000..d18b2e1 --- /dev/null +++ b/src/utils/time.js @@ -0,0 +1,29 @@ +/** + * https://stackoverflow.com/a/3177838 + */ +const timeSince = (date) => { + const seconds = Math.floor((new Date() - date) / 1000); + let interval = seconds / 31536000; + if (interval > 1) { + return `${Math.floor(interval)} years ago`; + } + interval = seconds / 2592000; + if (interval > 1) { + return `${Math.floor(interval)} months ago`; + } + interval = seconds / 86400; + if (interval > 1) { + return `${Math.floor(interval)} days ago`; + } + interval = seconds / 3600; + if (interval > 1) { + return `${Math.floor(interval)} hours ago`; + } + interval = seconds / 60; + if (interval > 1) { + return `${Math.floor(interval)} minutes ago`; + } + return `${Math.floor(seconds)} seconds ago`; +}; + +export default timeSince; diff --git a/src/utils/time.test.js b/src/utils/time.test.js new file mode 100644 index 0000000..ea40f5e --- /dev/null +++ b/src/utils/time.test.js @@ -0,0 +1,78 @@ +import moment from 'moment'; +import timeSince from './time'; + +test('basic case', () => { + expect( + timeSince( + Date.now(), + ), + ); +}); + +test('basic case 2', () => { + expect( + timeSince( + Date.now(), + ), + ).toBe('0 seconds ago'); +}); + +test('seconds ago', () => { + expect( + timeSince( + moment( + Date.now(), + ).subtract(30, 'seconds').toDate(), + ), + ).toBe('30 seconds ago'); +}); + +test('minutes ago', () => { + expect( + timeSince( + moment( + Date.now(), + ).subtract(15, 'minutes').toDate(), + ), + ).toBe('15 minutes ago'); +}); + +test('hours ago', () => { + expect( + timeSince( + moment( + Date.now(), + ).subtract(6, 'hours').toDate(), + ), + ).toBe('6 hours ago'); +}); + +test('days ago', () => { + expect( + timeSince( + moment( + Date.now(), + ).subtract(3, 'days').toDate(), + ), + ).toBe('3 days ago'); +}); + +test('months ago', () => { + expect( + timeSince( + moment( + Date.now(), + ).subtract(6, 'months').toDate(), + ), + ).toBe('6 months ago'); +}); + +test('years ago', () => { + expect( + timeSince( + moment( + Date.now(), + ).subtract(1, 'years').toDate(), + ), + ).toBe('1 years ago'); +}); diff --git a/src/utils/validators.js b/src/utils/validators.js new file mode 100644 index 0000000..96a1698 --- /dev/null +++ b/src/utils/validators.js @@ -0,0 +1,17 @@ +const repoRegex = /https?:\/\/github.com\/(\w+)\/(\w+)/; + +const urlMatch = (url) => ( + url && url.match(repoRegex) +); + +/** + * Splits URL to owner and repo name. + */ +const splitUrl = (url) => ( + urlMatch(url).slice(1, 3) +); + +export { + urlMatch, + splitUrl, +}; diff --git a/yarn.lock b/yarn.lock index a5a34d2..547bd53 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,25 @@ # yarn lockfile v1 +"@apollo/client@^3.2.7": + version "3.2.7" + resolved "https://registry.yarnpkg.com/@apollo/client/-/client-3.2.7.tgz#1cae8d2f5e15c5d2135a288a9d18962e60c5194c" + integrity sha512-4G80jvBLqenCFUhwkHAAHi2ox6Ygq35BkE38yxammqykZm6KE3tVlcEKGOZi0jpiuGJPC6LIQ0d1gtI8ADPtmg== + dependencies: + "@graphql-typed-document-node/core" "^3.0.0" + "@types/zen-observable" "^0.8.0" + "@wry/context" "^0.5.2" + "@wry/equality" "^0.2.0" + fast-json-stable-stringify "^2.0.0" + graphql-tag "^2.11.0" + hoist-non-react-statics "^3.3.2" + optimism "^0.13.0" + prop-types "^15.7.2" + symbol-observable "^2.0.0" + ts-invariant "^0.5.0" + tslib "^1.10.0" + zen-observable "^0.8.14" + "@babel/code-frame@7.10.4", "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.5.5": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a" @@ -1085,7 +1104,7 @@ dependencies: regenerator-runtime "^0.13.4" -"@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": +"@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.4.2", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": version "7.12.5" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.5.tgz#410e7e487441e1b360c29be715d870d9b985882e" integrity sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg== @@ -1164,6 +1183,49 @@ minimatch "^3.0.4" strip-json-comments "^3.1.1" +"@fortawesome/fontawesome-common-types@^0.2.32": + version "0.2.32" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.32.tgz#3436795d5684f22742989bfa08f46f50f516f259" + integrity sha512-ux2EDjKMpcdHBVLi/eWZynnPxs0BtFVXJkgHIxXRl+9ZFaHPvYamAfCzeeQFqHRjuJtX90wVnMRaMQAAlctz3w== + +"@fortawesome/fontawesome-free@^5.15.1": + version "5.15.1" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.1.tgz#ccfef6ddbe59f8fe8f694783e1d3eb88902dc5eb" + integrity sha512-OEdH7SyC1suTdhBGW91/zBfR6qaIhThbcN8PUXtXilY4GYnSBbVqOntdHbC1vXwsDnX0Qix2m2+DSU1J51ybOQ== + +"@fortawesome/fontawesome-svg-core@^1.2.32": + version "1.2.32" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.32.tgz#da092bfc7266aa274be8604de610d7115f9ba6cf" + integrity sha512-XjqyeLCsR/c/usUpdWcOdVtWFVjPbDFBTQkn2fQRrWhhUoxriQohO2RWDxLyUM8XpD+Zzg5xwJ8gqTYGDLeGaQ== + dependencies: + "@fortawesome/fontawesome-common-types" "^0.2.32" + +"@fortawesome/free-brands-svg-icons@^5.15.1": + version "5.15.1" + resolved "https://registry.yarnpkg.com/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-5.15.1.tgz#1dc0563f4036639e53d24b8e532ea78a53ca2250" + integrity sha512-pkTZIWn7iuliCCgV+huDfZmZb2UjslalXGDA2PcqOVUYJmYL11y6ooFiMJkJvUZu+xgAc1gZgQe+Px12mZF0CA== + dependencies: + "@fortawesome/fontawesome-common-types" "^0.2.32" + +"@fortawesome/free-solid-svg-icons@^5.15.1": + version "5.15.1" + resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.15.1.tgz#e1432676ddd43108b41197fee9f86d910ad458ef" + integrity sha512-EFMuKtzRMNbvjab/SvJBaOOpaqJfdSap/Nl6hst7CgrJxwfORR1drdTV6q1Ib/JVzq4xObdTDcT6sqTaXMqfdg== + dependencies: + "@fortawesome/fontawesome-common-types" "^0.2.32" + +"@fortawesome/react-fontawesome@^0.1.12": + version "0.1.12" + resolved "https://registry.yarnpkg.com/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.12.tgz#fbdea86e8b73032895e6ded1ee1dbb1874902d1a" + integrity sha512-kV6HtqotM3K4YIXlTVvomuIi6QgGCvYm++ImyEx2wwgmSppZ6kbbA29ASwjAUBD63j2OFU0yoxeXpZkjrrX0qQ== + dependencies: + prop-types "^15.7.2" + +"@graphql-typed-document-node/core@^3.0.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@graphql-typed-document-node/core/-/core-3.1.0.tgz#0eee6373e11418bfe0b5638f654df7a4ca6a3950" + integrity sha512-wYn6r8zVZyQJ6rQaALBEln5B1pzxb9shV5Ef97kTvn6yVGrqyXVnDqnU24MXnFubR+rZjBY9NWuxX3FB2sTsjg== + "@hapi/address@2.x.x": version "2.1.4" resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5" @@ -1423,6 +1485,24 @@ schema-utils "^2.6.5" source-map "^0.7.3" +"@popperjs/core@^2.5.3": + version "2.5.4" + resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.5.4.tgz#de25b5da9f727985a3757fd59b5d028aba75841a" + integrity sha512-ZpKr+WTb8zsajqgDkvCEWgp6d5eJT6Q63Ng2neTbzBO76Lbe91vX/iVIW9dikq+Fs3yEo+ls4cxeXABD2LtcbQ== + +"@restart/context@^2.1.4": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@restart/context/-/context-2.1.4.tgz#a99d87c299a34c28bd85bb489cb07bfd23149c02" + integrity sha512-INJYZQJP7g+IoDUh/475NlGiTeMfwTXUEr3tmRneckHIxNolGOW9CTq83S8cxq0CgJwwcMzMJFchxvlwe7Rk8Q== + +"@restart/hooks@^0.3.21", "@restart/hooks@^0.3.25": + version "0.3.25" + resolved "https://registry.yarnpkg.com/@restart/hooks/-/hooks-0.3.25.tgz#11004139ad1c70d2f5965a8939dcb5aeb96aa652" + integrity sha512-m2v3N5pxTsIiSH74/sb1yW8D9RxkJidGW+5Mfwn/lHb2QzhZNlaU1su7abSyT9EGf0xS/0waLjrf7/XxQHUk7w== + dependencies: + lodash "^4.17.15" + lodash-es "^4.17.15" + "@rollup/plugin-node-resolve@^7.1.1": version "7.1.3" resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-7.1.3.tgz#80de384edfbd7bfc9101164910f86078151a3eca" @@ -1662,6 +1742,11 @@ dependencies: "@babel/types" "^7.3.0" +"@types/classnames@^2.2.10": + version "2.2.11" + resolved "https://registry.yarnpkg.com/@types/classnames/-/classnames-2.2.11.tgz#2521cc86f69d15c5b90664e4829d84566052c1cf" + integrity sha512-2koNhpWm3DgWRp5tpkiJ8JGc1xTn2q0l+jUNUE7oMKXUf5NpI9AIdC4kbjGNFBdHtcxBD18LAksoudAVhFKCjw== + "@types/eslint@^7.2.4": version "7.2.5" resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-7.2.5.tgz#92172ecf490c2fce4b076739693d75f30376d610" @@ -1700,6 +1785,11 @@ resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz#3c9ee980f1a10d6021ae6632ca3e79ca2ec4fb50" integrity sha512-giAlZwstKbmvMk1OO7WXSj4OZ0keXAcl2TQq4LWHiiPH2ByaH7WeUzng+Qej8UPxxv+8lRTuouo0iaNDBuzIBA== +"@types/invariant@^2.2.33": + version "2.2.34" + resolved "https://registry.yarnpkg.com/@types/invariant/-/invariant-2.2.34.tgz#05e4f79f465c2007884374d4795452f995720bbe" + integrity sha512-lYUtmJ9BqUN688fGY1U1HZoWT1/Jrmgigx2loq4ZcJpICECm/Om3V314BxdzypO0u5PORKGMM6x0OXaljV1YFg== + "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": version "2.0.3" resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#4ba8ddb720221f432e443bd5f9117fd22cfd4762" @@ -1762,11 +1852,38 @@ resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.1.5.tgz#b6ab3bba29e16b821d84e09ecfaded462b816b00" integrity sha512-UEyp8LwZ4Dg30kVU2Q3amHHyTn1jEdhCIE59ANed76GaT1Vp76DD3ZWSAxgCrw6wJ0TqeoBpqmfUHiUDPs//HQ== +"@types/prop-types@*", "@types/prop-types@^15.7.3": + version "15.7.3" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7" + integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw== + "@types/q@^1.5.1": version "1.5.4" resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.4.tgz#15925414e0ad2cd765bfef58842f7e26a7accb24" integrity sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug== +"@types/react-transition-group@^4.4.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.0.tgz#882839db465df1320e4753e6e9f70ca7e9b4d46d" + integrity sha512-/QfLHGpu+2fQOqQaXh8MG9q03bFENooTb/it4jr5kKaZlDQfWvjqWZg48AwzPVMBHlRuTRAY7hRHCEOXz5kV6w== + dependencies: + "@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== + dependencies: + "@types/prop-types" "*" + csstype "^3.0.2" + +"@types/react@^16.9.11", "@types/react@^16.9.35": + version "16.14.1" + resolved "https://registry.yarnpkg.com/@types/react/-/react-16.14.1.tgz#da2ecb638385614a5573e16e4aa7daf936dbead5" + integrity sha512-32mxrbX62m5b+lMTSzucFKNIr8Eq4T6T3rDVxYzKqyRwyfnPcwZppWW0YXUlPNPUE+r6phBtHXYRgr8ad/Zl9A== + dependencies: + "@types/prop-types" "*" + "@types/resolve@0.0.8": version "0.0.8" resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-0.0.8.tgz#f26074d238e02659e323ce1a13d041eee280e194" @@ -1803,6 +1920,11 @@ dependencies: source-map "^0.6.1" +"@types/warning@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/warning/-/warning-3.0.0.tgz#0d2501268ad8f9962b740d387c4654f5f8e23e52" + integrity sha1-DSUBJorY+ZYrdA04fEZU9fjiPlI= + "@types/webpack-sources@*": version "2.0.0" resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-2.0.0.tgz#08216ab9be2be2e1499beaebc4d469cec81e82a7" @@ -1836,6 +1958,11 @@ dependencies: "@types/yargs-parser" "*" +"@types/zen-observable@^0.8.0": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.8.1.tgz#5668c0bce55a91f2b9566b1d8a4c0a8dbbc79764" + integrity sha512-wmk0xQI6Yy7Fs/il4EpOcflG4uonUpYGqvZARESLc2oy4u69fkatFLbJOeW4Q6awO15P4rduAe6xkwHevpXcUQ== + "@typescript-eslint/eslint-plugin@^4.5.0": version "4.8.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.8.1.tgz#b362abe0ee478a6c6d06c14552a6497f0b480769" @@ -2088,6 +2215,20 @@ "@webassemblyjs/wast-parser" "1.9.0" "@xtuc/long" "4.2.2" +"@wry/context@^0.5.2": + version "0.5.2" + resolved "https://registry.yarnpkg.com/@wry/context/-/context-0.5.2.tgz#f2a5d5ab9227343aa74c81e06533c1ef84598ec7" + integrity sha512-B/JLuRZ/vbEKHRUiGj6xiMojST1kHhu4WcreLfNN7q9DqQFrb97cWgf/kiYsPSUCAMVN0HzfFc8XjJdzgZzfjw== + dependencies: + tslib "^1.9.3" + +"@wry/equality@^0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@wry/equality/-/equality-0.2.0.tgz#a312d1b6a682d0909904c2bcd355b02303104fb7" + integrity sha512-Y4d+WH6hs+KZJUC8YKLYGarjGekBrhslDbf/R20oV+AakHPINSitHfDRQz3EGcEWc1luXYNUvMhawWtZVWNGvQ== + dependencies: + tslib "^1.9.3" + "@xtuc/ieee754@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" @@ -2417,7 +2558,7 @@ async-limiter@~1.0.0: resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== -async@^2.6.2: +async@^2.6.1, async@^2.6.2: version "2.6.3" resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== @@ -2703,6 +2844,13 @@ bindings@^1.5.0: dependencies: file-uri-to-path "1.0.0" +block-stream@*: + version "0.0.9" + resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" + integrity sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo= + dependencies: + inherits "~2.0.0" + bluebird@^3.5.5: version "3.7.2" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" @@ -2751,6 +2899,11 @@ boolbase@^1.0.0, boolbase@~1.0.0: resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= +bootstrap@^4.5.3: + version "4.5.3" + resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.5.3.tgz#c6a72b355aaf323920be800246a6e4ef30997fe6" + integrity sha512-o9ppKQioXGqhw8Z7mah6KdTYpNQY//tipnkxppWhPbiSWdD+1raYsnhwEZjkTHYbGee4cVQ0Rx65EhOY/HNLcQ== + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -3180,6 +3333,11 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" +classnames@^2.2.5, classnames@^2.2.6: + version "2.2.6" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce" + integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q== + clean-css@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.3.tgz#507b5de7d97b48ee53d84adb0160ff6216380f78" @@ -3298,7 +3456,7 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" -commander@^2.20.0: +commander@^2.18.0, commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== @@ -3501,6 +3659,17 @@ cosmiconfig@^7.0.0: path-type "^4.0.0" yaml "^1.10.0" +coveralls@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/coveralls/-/coveralls-3.1.0.tgz#13c754d5e7a2dd8b44fe5269e21ca394fb4d615b" + integrity sha512-sHxOu2ELzW8/NC1UP5XVLbZDzO4S3VxfFye3XYCznopHy02YjNkHcj5bKaVw2O7hVaBdBjEdQGpie4II1mWhuQ== + dependencies: + js-yaml "^3.13.1" + lcov-parse "^1.0.0" + log-driver "^1.2.7" + minimist "^1.2.5" + request "^2.88.2" + create-ecdh@^4.0.0: version "4.0.4" resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" @@ -3809,6 +3978,11 @@ cssstyle@^2.2.0: dependencies: cssom "~0.3.6" +csstype@^3.0.2: + version "3.0.5" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.5.tgz#7fdec6a28a67ae18647c51668a9ff95bb2fa7bb8" + integrity sha512-uVDi8LpBUKQj6sdxNaTetL6FpeCqTjOvAQuQUa/qAqq8oOd4ivkbhgnqayl0dnPal8Tb/yB1tF+gOvCBiicaiQ== + cyclist@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" @@ -4072,6 +4246,14 @@ dom-converter@^0.2: dependencies: utila "~0.4" +dom-helpers@^5.0.1, dom-helpers@^5.1.2, dom-helpers@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.0.tgz#57fd054c5f8f34c52a3eeffdb7e7e93cd357d95b" + integrity sha512-Ru5o9+V8CpunKnz5LGgWXkmrH/20cGKwcHwS4m73zIvs54CN9epEmT/HLqFJW3kXpakAFkEdzgy1hzlJe3E4OQ== + dependencies: + "@babel/runtime" "^7.8.7" + csstype "^3.0.2" + dom-serializer@0: version "0.2.2" resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" @@ -4201,6 +4383,11 @@ elliptic@^6.5.3: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.0" +email-addresses@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/email-addresses/-/email-addresses-3.1.0.tgz#cabf7e085cbdb63008a70319a74e6136188812fb" + integrity sha512-k0/r7GrWVL32kZlGwfPNgB2Y/mMXVTq/decgLczm/j34whdaspNrZO8CnXPf1laaHxI6ptUlsnAxN+UAPw+fzg== + emittery@^0.7.1: version "0.7.2" resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.7.2.tgz#25595908e13af0f5674ab419396e2fb394cdfa82" @@ -4375,7 +4562,7 @@ escape-string-regexp@2.0.0, escape-string-regexp@^2.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== -escape-string-regexp@^1.0.5: +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= @@ -4392,6 +4579,24 @@ escodegen@^1.14.1: optionalDependencies: source-map "~0.6.1" +eslint-config-airbnb-base@^14.2.1: + 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@^18.2.1: + version "18.2.1" + resolved "https://registry.yarnpkg.com/eslint-config-airbnb/-/eslint-config-airbnb-18.2.1.tgz#b7fe2b42f9f8173e825b73c8014b592e449c98d9" + integrity sha512-glZNDEZ36VdlZWoxn/bUR1r/sdFKPd1mHPbqUtkctgNG4yT2DLLtJ3D+yCV+jzZCc2V1nBVkmdknOJBZ5Hc0fg== + dependencies: + eslint-config-airbnb-base "^14.2.1" + object.assign "^4.1.2" + object.entries "^1.1.2" + 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" @@ -4895,6 +5100,28 @@ file-uri-to-path@1.0.0: resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== +filename-reserved-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/filename-reserved-regex/-/filename-reserved-regex-1.0.0.tgz#e61cf805f0de1c984567d0386dc5df50ee5af7e4" + integrity sha1-5hz4BfDeHJhFZ9A4bcXfUO5a9+Q= + +filenamify-url@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/filenamify-url/-/filenamify-url-1.0.0.tgz#b32bd81319ef5863b73078bed50f46a4f7975f50" + integrity sha1-syvYExnvWGO3MHi+1Q9GpPeXX1A= + dependencies: + filenamify "^1.0.0" + humanize-url "^1.0.0" + +filenamify@^1.0.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/filenamify/-/filenamify-1.2.1.tgz#a9f2ffd11c503bed300015029272378f1f1365a5" + integrity sha1-qfL/0RxQO+0wABUCknI3jx8TZaU= + dependencies: + filename-reserved-regex "^1.0.0" + strip-outer "^1.0.0" + trim-repeated "^1.0.0" + filesize@6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/filesize/-/filesize-6.1.0.tgz#e81bdaa780e2451d714d71c0d7a4f3238d37ad00" @@ -5002,6 +5229,11 @@ follow-redirects@^1.0.0: resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.0.tgz#b42e8d93a2a7eea5ed88633676d6597bc8e384db" integrity sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA== +font-awesome@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/font-awesome/-/font-awesome-4.7.0.tgz#8fa8cf0411a1a31afd07b06d2902bb9fc815a133" + integrity sha1-j6jPBBGhoxr9B7BtKQK7n8gVoTM= + for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" @@ -5127,6 +5359,16 @@ fsevents@~2.1.2: resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== +fstream@1.0.12, fstream@^1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.12.tgz#4e8ba8ee2d48be4f7d0de505455548eae5932045" + integrity sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg== + dependencies: + graceful-fs "^4.1.2" + inherits "~2.0.0" + mkdirp ">=0.5 0" + rimraf "2" + function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" @@ -5192,6 +5434,19 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" +gh-pages@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/gh-pages/-/gh-pages-3.1.0.tgz#ec3ed0f6a6e3fc3d888758fa018f08191c96bd55" + integrity sha512-3b1rly9kuf3/dXsT8+ZxP0UhNLOo1CItj+3e31yUVcaph/yDsJ9RzD7JOw5o5zpBTJVQLlJAASNkUfepi9fe2w== + dependencies: + async "^2.6.1" + commander "^2.18.0" + email-addresses "^3.0.1" + filenamify-url "^1.0.0" + find-cache-dir "^3.3.1" + fs-extra "^8.1.0" + globby "^6.1.0" + glob-parent@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" @@ -5275,6 +5530,16 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6 resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== +graphql-tag@^2.11.0: + version "2.11.0" + resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.11.0.tgz#1deb53a01c46a7eb401d6cb59dec86fa1cccbffd" + integrity sha512-VmsD5pJqWJnQZMUeRwrDhfgoyqcfwEkvtpANqcoUG8/tOLkwNgU9mzub/Mc78OJMhHjx7gfAMTxzdG43VGg3bA== + +graphql@^15.4.0: + version "15.4.0" + resolved "https://registry.yarnpkg.com/graphql/-/graphql-15.4.0.tgz#e459dea1150da5a106486ba7276518b5295a4347" + integrity sha512-EB3zgGchcabbsU9cFe1j+yxdzKQKAbGUWRb13DsrsMN1yyfmmIq+2+L5MqVWcDCE4V89R5AyUOi7sMOGxdsYtA== + growly@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" @@ -5400,6 +5665,13 @@ hmac-drbg@^1.0.0: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.1" +hoist-non-react-statics@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" + integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== + dependencies: + react-is "^16.7.0" + hoopy@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/hoopy/-/hoopy-0.1.4.tgz#609207d661100033a9a9402ad3dea677381c1b1d" @@ -5572,6 +5844,14 @@ human-signals@^1.1.1: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== +humanize-url@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/humanize-url/-/humanize-url-1.0.1.tgz#f4ab99e0d288174ca4e1e50407c55fbae464efff" + integrity sha1-9KuZ4NKIF0yk4eUEB8VfuuRk7/8= + dependencies: + normalize-url "^1.0.0" + strip-url-auth "^1.0.0" + iconv-lite@0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -5692,7 +5972,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -5729,6 +6009,13 @@ internal-slot@^1.0.2: has "^1.0.3" side-channel "^1.0.2" +invariant@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== + dependencies: + loose-envify "^1.0.0" + ip-regex@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" @@ -6767,6 +7054,11 @@ last-call-webpack-plugin@^3.0.0: lodash "^4.17.5" webpack-sources "^1.1.0" +lcov-parse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcov-parse/-/lcov-parse-1.0.0.tgz#eb0d46b54111ebc561acb4c408ef9363bdc8f7e0" + integrity sha1-6w1GtUER68VhrLTECO+TY73I9+A= + leven@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" @@ -6858,6 +7150,11 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" +lodash-es@^4.17.15: + version "4.17.15" + resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.15.tgz#21bd96839354412f23d7a10340e5eac6ee455d78" + integrity sha512-rlrc3yU3+JNOpZ9zj5pQtxnx2THmvRykwL4Xlxoa8I9lHBlVbbyPhgyPMioxVZ4NqyxaVVtaJnzsyOidQIhyyQ== + lodash._reinterpolate@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" @@ -6898,12 +7195,17 @@ lodash.uniq@^4.5.0: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== +log-driver@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/log-driver/-/log-driver-1.2.7.tgz#63b95021f0702fedfa2c9bb0a24e7797d71871d8" + integrity sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg== + loglevel@^1.6.8: version "1.7.0" resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.0.tgz#728166855a740d59d38db01cf46f042caa041bb0" integrity sha512-i2sY04nal5jDcagM3FMfG++T69GEEM8CYuOfeOIvmXzOIcwE9a/CJPR0MFM97pYMj/u10lzz7/zd7+qwhrBTqQ== -loose-envify@^1.1.0, loose-envify@^1.4.0: +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -7206,7 +7508,7 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" -mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.5, mkdirp@~0.5.1: +"mkdirp@>=0.5 0", mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.5, mkdirp@~0.5.1: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== @@ -7218,6 +7520,11 @@ mkdirp@^1.0.3, mkdirp@^1.0.4: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== +moment@^2.29.1: + version "2.29.1" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3" + integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ== + move-concurrently@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" @@ -7413,7 +7720,7 @@ normalize-range@^0.1.2: resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI= -normalize-url@1.9.1: +normalize-url@1.9.1, normalize-url@^1.0.0: version "1.9.1" resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-1.9.1.tgz#2cc0d66b31ea23036458436e3620d85954c66c3c" integrity sha1-LMDWazHqIwNkWENuNiDYWVTGbDw= @@ -7503,7 +7810,7 @@ object-visit@^1.0.0: dependencies: isobject "^3.0.0" -object.assign@^4.1.0, object.assign@^4.1.1: +object.assign@^4.1.0, object.assign@^4.1.1, object.assign@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== @@ -7603,6 +7910,13 @@ opn@^5.5.0: dependencies: is-wsl "^1.1.0" +optimism@^0.13.0: + version "0.13.1" + resolved "https://registry.yarnpkg.com/optimism/-/optimism-0.13.1.tgz#df2e6102c973f870d6071712fffe4866bb240384" + integrity sha512-16RRVYZe8ODcUqpabpY7Gb91vCAbdhn8FHjlUb2Hqnjjow1j8Z1dlppds+yAsLbreNTVylLC+tNX6DuC2vt3Kw== + dependencies: + "@wry/context" "^0.5.2" + optimize-css-assets-webpack-plugin@5.0.4: version "5.0.4" resolved "https://registry.yarnpkg.com/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.4.tgz#85883c6528aaa02e30bbad9908c92926bb52dc90" @@ -7728,6 +8042,11 @@ p-try@^2.0.0: resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== +paginator@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/paginator/-/paginator-1.0.0.tgz#7565702af9ab9616dca61fc22c70eba2a4357265" + integrity sha1-dWVwKvmrlhbcph/CLHDroqQ1cmU= + pako@~1.0.5: version "1.0.11" resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" @@ -8722,7 +9041,15 @@ prompts@2.4.0, prompts@^2.0.1: kleur "^3.0.3" sisteransi "^1.0.5" -prop-types@^15.7.2: +prop-types-extra@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/prop-types-extra/-/prop-types-extra-1.1.1.tgz#58c3b74cbfbb95d304625975aa2f0848329a010b" + integrity sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew== + dependencies: + react-is "^16.3.2" + warning "^4.0.0" + +"prop-types@15.x.x - 16.x.x", prop-types@^15.6.2, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== @@ -8888,6 +9215,30 @@ react-app-polyfill@^2.0.0: regenerator-runtime "^0.13.7" whatwg-fetch "^3.4.1" +react-bootstrap@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/react-bootstrap/-/react-bootstrap-1.4.0.tgz#806a8b48b065cedfb28c6c5c7b0c0e3c3b53445d" + integrity sha512-0BMzgeUAxH126v7VYDzIXbHxQVHSnniPVKpz9fblumdQpWaiElMnnzk+u8h8DoELX0nCXwPlcUzgXqmpncdc2Q== + dependencies: + "@babel/runtime" "^7.4.2" + "@restart/context" "^2.1.4" + "@restart/hooks" "^0.3.21" + "@types/classnames" "^2.2.10" + "@types/invariant" "^2.2.33" + "@types/prop-types" "^15.7.3" + "@types/react" "^16.9.35" + "@types/react-transition-group" "^4.4.0" + "@types/warning" "^3.0.0" + classnames "^2.2.6" + dom-helpers "^5.1.2" + invariant "^2.2.4" + prop-types "^15.7.2" + prop-types-extra "^1.1.0" + react-overlays "^4.1.0" + react-transition-group "^4.4.1" + uncontrollable "^7.0.0" + warning "^4.0.3" + 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" @@ -8932,15 +9283,46 @@ react-error-overlay@^6.0.8: resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.8.tgz#474ed11d04fc6bda3af643447d85e9127ed6b5de" integrity sha512-HvPuUQnLp5H7TouGq3kzBeioJmXms1wHy9EGjz2OURWBp4qZO6AfGEcnxts1D/CbwPLRAgTMPCEgYhA3sEM4vw== -react-is@^16.8.1: +"react-is@^16.12.0 || ^17.0.0", react-is@^17.0.1: + version "17.0.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.1.tgz#5b3531bd76a645a4c9fb6e693ed36419e3301339" + integrity sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA== + +react-is@^16.3.2, react-is@^16.7.0, react-is@^16.8.1: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== -react-is@^17.0.1: - version "17.0.1" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.1.tgz#5b3531bd76a645a4c9fb6e693ed36419e3301339" - integrity sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA== +react-js-pagination@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/react-js-pagination/-/react-js-pagination-3.0.3.tgz#bc5504ad9fda2a13f59eca91c7b07966a39e1776" + integrity sha512-podyA6Rd0uxc8uQakXWXxnonoOPI6NnFOROXfc6qPKNYm44s+Bgpn0JkyflcfbHf/GFKahnL8JN8rxBHZiBskg== + dependencies: + classnames "^2.2.5" + fstream "1.0.12" + paginator "^1.0.0" + prop-types "15.x.x - 16.x.x" + react "15.x.x - 16.x.x" + tar "2.2.2" + +react-lifecycles-compat@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" + integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== + +react-overlays@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/react-overlays/-/react-overlays-4.1.1.tgz#0060107cbe1c5171a744ccda3fbf0556d064bc5f" + integrity sha512-WtJifh081e6M24KnvTQoNjQEpz7HoLxqt8TwZM7LOYIkYJ8i/Ly1Xi7RVte87ZVnmqQ4PFaFiNHZhSINPSpdBQ== + dependencies: + "@babel/runtime" "^7.12.1" + "@popperjs/core" "^2.5.3" + "@restart/hooks" "^0.3.25" + "@types/warning" "^3.0.0" + dom-helpers "^5.2.0" + prop-types "^15.7.2" + uncontrollable "^7.0.0" + warning "^4.0.3" react-refresh@^0.8.3: version "0.8.3" @@ -9013,6 +9395,43 @@ react-scripts@4.0.1: optionalDependencies: fsevents "^2.1.3" +react-shallow-renderer@^16.13.1: + version "16.14.1" + resolved "https://registry.yarnpkg.com/react-shallow-renderer/-/react-shallow-renderer-16.14.1.tgz#bf0d02df8a519a558fd9b8215442efa5c840e124" + integrity sha512-rkIMcQi01/+kxiTE9D3fdS959U1g7gs+/rborw++42m1O9FAQiNI/UNRZExVUoAOprn4umcXf+pFRou8i4zuBg== + dependencies: + object-assign "^4.1.1" + react-is "^16.12.0 || ^17.0.0" + +react-test-renderer@^17.0.1: + version "17.0.1" + resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-17.0.1.tgz#3187e636c3063e6ae498aedf21ecf972721574c7" + integrity sha512-/dRae3mj6aObwkjCcxZPlxDFh73XZLgvwhhyON2haZGUEhiaY5EjfAdw+d/rQmlcFwdTpMXCSGVk374QbCTlrA== + dependencies: + object-assign "^4.1.1" + react-is "^17.0.1" + react-shallow-renderer "^16.13.1" + scheduler "^0.20.1" + +react-transition-group@^4.4.1: + version "4.4.1" + resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.1.tgz#63868f9325a38ea5ee9535d828327f85773345c9" + integrity sha512-Djqr7OQ2aPUiYurhPalTrVy9ddmFCCzwhqQmtN+J3+3DzLO209Fdr70QrN8Z3DsglWql6iY1lDWAfpFiBtuKGw== + dependencies: + "@babel/runtime" "^7.5.5" + dom-helpers "^5.0.1" + loose-envify "^1.4.0" + prop-types "^15.6.2" + +"react@15.x.x - 16.x.x": + version "16.14.0" + resolved "https://registry.yarnpkg.com/react/-/react-16.14.0.tgz#94d776ddd0aaa37da3eda8fc5b6b18a4c9a3114d" + integrity sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.2" + react@^17.0.1: version "17.0.1" resolved "https://registry.yarnpkg.com/react/-/react-17.0.1.tgz#6e0600416bd57574e3f86d92edba3d9008726127" @@ -9381,6 +9800,13 @@ rgba-regex@^1.0.0: resolved "https://registry.yarnpkg.com/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3" integrity sha1-QzdOLiyglosO8VI0YLfXMP8i7rM= +rimraf@2, rimraf@^2.5.4, rimraf@^2.6.3: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + rimraf@2.6.3: version "2.6.3" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" @@ -9388,13 +9814,6 @@ rimraf@2.6.3: dependencies: glob "^7.1.3" -rimraf@^2.5.4, rimraf@^2.6.3: - version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" - integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== - dependencies: - glob "^7.1.3" - rimraf@^3.0.0, rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" @@ -10189,6 +10608,18 @@ strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== +strip-outer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strip-outer/-/strip-outer-1.0.1.tgz#b2fd2abf6604b9d1e6013057195df836b8a9d631" + integrity sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg== + dependencies: + escape-string-regexp "^1.0.2" + +strip-url-auth@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strip-url-auth/-/strip-url-auth-1.0.1.tgz#22b0fa3a41385b33be3f331551bbb837fa0cd7ae" + integrity sha1-IrD6OkE4WzO+PzMVUbu4N/oM164= + style-loader@1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-1.3.0.tgz#828b4a3b3b7e7aa5847ce7bae9e874512114249e" @@ -10259,6 +10690,11 @@ svgo@^1.0.0, svgo@^1.2.2: unquote "~1.1.1" util.promisify "~1.0.0" +symbol-observable@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-2.0.3.tgz#5b521d3d07a43c351055fa43b8355b62d33fd16a" + integrity sha512-sQV7phh2WCYAn81oAkakC5qjq2Ml0g8ozqz03wOGnx9dDlG1de6yrF+0RAzSJD8fPUow3PTSMf2SAbOGxb93BA== + symbol-tree@^3.2.4: version "3.2.4" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" @@ -10279,6 +10715,15 @@ tapable@^1.0.0, tapable@^1.1.3: resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== +tar@2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.2.tgz#0ca8848562c7299b8b446ff6a4d60cdbb23edc40" + integrity sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA== + dependencies: + block-stream "*" + fstream "^1.0.12" + inherits "2" + tar@^6.0.2: version "6.0.5" resolved "https://registry.yarnpkg.com/tar/-/tar-6.0.5.tgz#bde815086e10b39f1dcd298e89d596e1535e200f" @@ -10481,11 +10926,25 @@ tr46@^2.0.2: dependencies: punycode "^2.1.1" +trim-repeated@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/trim-repeated/-/trim-repeated-1.0.0.tgz#e3646a2ea4e891312bf7eace6cfb05380bc01c21" + integrity sha1-42RqLqTokTEr9+rObPsFOAvAHCE= + dependencies: + escape-string-regexp "^1.0.2" + tryer@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8" integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA== +ts-invariant@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/ts-invariant/-/ts-invariant-0.5.1.tgz#4171fdb85f72a40381c147afd97c12154ada2abc" + integrity sha512-k3UpDNrBZpqJFnAAkAHNmSHtNuCxcU6xLiziPgalHRKZHme6T6jnKC8CcXDmk1zbHLQM8pc+rNC1Q6FvXMAl+g== + dependencies: + tslib "^1.9.3" + ts-pnp@1.2.0, ts-pnp@^1.1.6: version "1.2.0" resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92" @@ -10501,7 +10960,7 @@ tsconfig-paths@^3.9.0: minimist "^1.2.0" strip-bom "^3.0.0" -tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0: +tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== @@ -10599,6 +11058,16 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= +uncontrollable@^7.0.0: + version "7.1.1" + resolved "https://registry.yarnpkg.com/uncontrollable/-/uncontrollable-7.1.1.tgz#f67fed3ef93637126571809746323a9db815d556" + integrity sha512-EcPYhot3uWTS3w00R32R2+vS8Vr53tttrvMj/yA1uYRhf8hbTG2GyugGqWDY0qIskxn0uTTojVd6wPYW9ZEf8Q== + dependencies: + "@babel/runtime" "^7.6.3" + "@types/react" "^16.9.11" + invariant "^2.2.4" + react-lifecycles-compat "^3.0.4" + unicode-canonical-property-names-ecmascript@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" @@ -10872,6 +11341,13 @@ walker@^1.0.7, walker@~1.0.5: dependencies: makeerror "1.0.x" +warning@^4.0.0, warning@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3" + integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w== + dependencies: + loose-envify "^1.0.0" + watchpack-chokidar2@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz#38500072ee6ece66f3769936950ea1771be1c957" @@ -11390,3 +11866,8 @@ yargs@^15.4.1: which-module "^2.0.0" y18n "^4.0.0" yargs-parser "^18.1.2" + +zen-observable@^0.8.14: + version "0.8.15" + resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.15.tgz#96415c512d8e3ffd920afd3889604e30b9eaac15" + integrity sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==