diff --git a/.gitignore b/.gitignore
index 4d29575de..81b368c54 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,3 +21,5 @@
npm-debug.log*
yarn-debug.log*
yarn-error.log*
+
+.vercel
diff --git a/coverage.txt b/coverage.txt
new file mode 100644
index 000000000..ae0f3f72a
--- /dev/null
+++ b/coverage.txt
@@ -0,0 +1,11 @@
+yarn run v1.22.10
+$ react-scripts test --coverage
+No tests found related to files changed since last commit.
+----------|----------|----------|----------|----------|-------------------|
+File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
+----------|----------|----------|----------|----------|-------------------|
+All files | 0 | 0 | 0 | 0 | |
+----------|----------|----------|----------|----------|-------------------|
+
+
+[1B[JDone in 7.95s.
diff --git a/package.json b/package.json
index 5bc0e0d0d..bb5e91f4d 100644
--- a/package.json
+++ b/package.json
@@ -6,11 +6,16 @@
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^10.4.9",
"@testing-library/user-event": "^12.1.3",
+ "enzyme": "^3.11.0",
+ "enzyme-adapter-react-16": "^1.15.6",
"react": "^16.13.1",
"react-dom": "^16.13.1",
+ "react-query": "^3.13.4",
"react-router": "^5.2.0",
"react-router-dom": "^5.2.0",
- "react-scripts": "3.4.3"
+ "react-scripts": "3.4.3",
+ "sanitize.css": "^12.0.1",
+ "styled-components": "^5.2.1"
},
"scripts": {
"start": "react-scripts start",
@@ -57,5 +62,8 @@
"hooks": {
"pre-commit": "lint-staged"
}
+ },
+ "resolutions": {
+ "styled-components": "^5"
}
}
diff --git a/src/components/App/App.component.jsx b/src/components/App/App.component.jsx
index e372d6849..5666cfb45 100644
--- a/src/components/App/App.component.jsx
+++ b/src/components/App/App.component.jsx
@@ -1,15 +1,21 @@
import React, { useLayoutEffect } from 'react';
-import { BrowserRouter, Switch, Route } from 'react-router-dom';
+import { BrowserRouter, Switch, Route, useRouteMatch } from 'react-router-dom';
+import { QueryClient, QueryClientProvider } from 'react-query';
-import AuthProvider from '../../providers/Auth';
-import HomePage from '../../pages/Home';
+import AuthProvider, { useAuth } from '../../providers/Auth';
import LoginPage from '../../pages/Login';
import NotFound from '../../pages/NotFound';
-import SecretPage from '../../pages/Secret';
-import Private from '../Private';
-import Fortune from '../Fortune';
import Layout from '../Layout';
import { random } from '../../utils/fns';
+import { YouTubeProvider } from '../YouTube/YouTubeProvider';
+import MyThemeProvider from './MyThemeProvider';
+import VideoList from '../YouTube/List/VideoList';
+import VideoDetail from '../YouTube/Detail/VideoDetail';
+
+const ProtectedRoute = (props) => {
+ const { authenticated } = useAuth();
+ return authenticated ? : ;
+};
function App() {
useLayoutEffect(() => {
@@ -33,26 +39,50 @@ function App() {
return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
);
}
+export const queryClient = new QueryClient();
+function VideosRoute() {
+ const { path } = useRouteMatch();
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
export default App;
diff --git a/src/components/App/MyThemeProvider.jsx b/src/components/App/MyThemeProvider.jsx
new file mode 100644
index 000000000..f5410193a
--- /dev/null
+++ b/src/components/App/MyThemeProvider.jsx
@@ -0,0 +1,19 @@
+import React from 'react';
+import { ThemeProvider } from 'styled-components';
+import { useYouTube } from '../YouTube/YouTubeProvider';
+
+const theme = {
+ dark: {
+ primary: '#4396f3',
+ secondary: '#4a4646',
+ color: '#f7f7f7',
+ },
+};
+
+function MyThemeProvider({ children }) {
+ const { state } = useYouTube();
+ const { theme: stateTheme } = state;
+ return {children};
+}
+
+export default MyThemeProvider;
diff --git a/src/components/FavoritesButton/FavoritesButton.jsx b/src/components/FavoritesButton/FavoritesButton.jsx
new file mode 100644
index 000000000..26edcaf93
--- /dev/null
+++ b/src/components/FavoritesButton/FavoritesButton.jsx
@@ -0,0 +1,31 @@
+import React, { useEffect, useState } from 'react';
+import { Loading, StyledFavoritesButton } from './FavoritesButton.styled';
+import useFavorites from './useFavorites';
+
+const FavoritesButton = ({ videoId }) => {
+ const { favorites, updateFavorites, isLoading } = useFavorites();
+ const [isFavorite, setIsFavorite] = useState(false);
+ const [label, setLabel] = useState();
+
+ useEffect(() => {
+ const found = favorites.some((id) => id === videoId);
+ setLabel(found ? 'Remove from Favorites' : 'Add to Favorites');
+ setIsFavorite(found);
+ }, [favorites, videoId]);
+
+ const handleClick = (event) => {
+ event.stopPropagation();
+
+ const newFavorites = isFavorite
+ ? favorites.filter((id) => id !== videoId)
+ : [...favorites, videoId];
+
+ updateFavorites(newFavorites);
+ };
+
+ if (isLoading || !label) return Loading...;
+
+ return {label};
+};
+
+export default FavoritesButton;
diff --git a/src/components/FavoritesButton/FavoritesButton.styled.js b/src/components/FavoritesButton/FavoritesButton.styled.js
new file mode 100644
index 000000000..a10c9c72c
--- /dev/null
+++ b/src/components/FavoritesButton/FavoritesButton.styled.js
@@ -0,0 +1,12 @@
+import styled from 'styled-components';
+
+const StyledFavoritesButton = styled.button`
+ font-size: 12px;
+ max-width: 150px;
+`;
+
+const Loading = styled.span`
+ font-size: 12px;
+`;
+
+export { StyledFavoritesButton, Loading };
diff --git a/src/components/FavoritesButton/useFavorites.js b/src/components/FavoritesButton/useFavorites.js
new file mode 100644
index 000000000..6dfddc699
--- /dev/null
+++ b/src/components/FavoritesButton/useFavorites.js
@@ -0,0 +1,12 @@
+import { useLocalStorage } from '../../utils/useLocalStorage';
+
+const useFavorites = () => {
+ const { data: favorites, mutation, isLoading } = useLocalStorage({
+ cacheKey: 'favorites',
+ initialData: [],
+ });
+
+ return { favorites, updateFavorites: mutation.mutate, isLoading };
+};
+
+export default useFavorites;
diff --git a/src/components/Fortune/Fortune.component.jsx b/src/components/Fortune/Fortune.component.jsx
deleted file mode 100644
index fdd00219c..000000000
--- a/src/components/Fortune/Fortune.component.jsx
+++ /dev/null
@@ -1,12 +0,0 @@
-import React from 'react';
-
-import { useFortune } from '../../utils/hooks/useFortune';
-import './Fortune.styles.css';
-
-function Fortune() {
- const { fortune } = useFortune();
-
- return {fortune} ;
-}
-
-export default Fortune;
diff --git a/src/components/Fortune/Fortune.styles.css b/src/components/Fortune/Fortune.styles.css
deleted file mode 100644
index 360014874..000000000
--- a/src/components/Fortune/Fortune.styles.css
+++ /dev/null
@@ -1,5 +0,0 @@
-.fortune {
- position: fixed;
- bottom: 0;
- right: 0;
-}
diff --git a/src/components/Fortune/index.js b/src/components/Fortune/index.js
deleted file mode 100644
index 3e887bf31..000000000
--- a/src/components/Fortune/index.js
+++ /dev/null
@@ -1 +0,0 @@
-export { default } from './Fortune.component';
diff --git a/src/components/Layout/Header/Header.jsx b/src/components/Layout/Header/Header.jsx
new file mode 100644
index 000000000..e2b041e3b
--- /dev/null
+++ b/src/components/Layout/Header/Header.jsx
@@ -0,0 +1,59 @@
+import React from 'react';
+import { useHistory } from 'react-router-dom';
+import { useAuth } from '../../../providers/Auth';
+import { useYouTube } from '../../YouTube/YouTubeProvider';
+import { Col, TitleLink, HeaderContainer, Search, Space, Switch } from './Header.styled';
+
+const Header = () => {
+ const { state, dispatch } = useYouTube();
+ const { search = '', theme } = state;
+
+ const { authenticated, logout } = useAuth();
+ const history = useHistory();
+
+ const setSearch = (event) => {
+ dispatch({ type: 'search', payload: event.target.value });
+ };
+
+ return (
+
+
+ React Bootcamp
+
+
+
+
+
+
+ Videos
+
+
+ Favorites
+
+
+ {
+ dispatch({ type: 'switchTheme' });
+ }}
+ >
+ {theme === 'dark' ? 'Default' : 'Dark'}
+
+
+
+
+
+
+
+ );
+};
+
+export default Header;
diff --git a/src/components/Layout/Header/Header.styled.js b/src/components/Layout/Header/Header.styled.js
new file mode 100644
index 000000000..c4311b346
--- /dev/null
+++ b/src/components/Layout/Header/Header.styled.js
@@ -0,0 +1,56 @@
+import { NavLink } from 'react-router-dom';
+import styled from 'styled-components';
+
+const Col = styled.div`
+ display: flex;
+ flex-direction: column;
+ margin: 0 10px;
+`;
+
+const TitleLink = styled(NavLink)`
+ text-decoration: none;
+ color: black;
+ ${({ theme }) => (theme.color ? `color: ${theme.color}` : '')};
+`;
+
+const HeaderContainer = styled.div`
+ display: flex;
+ flex-direction: row;
+ height: 70px;
+ align-items: center;
+ padding: 5px;
+ border-bottom: 3px solid darkgray;
+ background-color: lightgray;
+ ${({ theme }) => (theme.primary ? `background-color: ${theme.primary}` : '')};
+ ${({ theme }) => (theme.color ? `color: ${theme.color}` : '')};
+`;
+
+const Search = styled.input`
+ background-color: lightyellow;
+ border: 0;
+ display: flex;
+ height: 1.8rem;
+ padding: 5px;
+`;
+
+const Space = styled.div`
+ display: flex;
+ flex: 1;
+`;
+
+const Switch = styled.span`
+ height: 40px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+`;
+
+const User = styled.span`
+ height: 40px;
+ background-color: springgreen;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+`;
+
+export { Col, TitleLink, HeaderContainer, Search, Space, Switch, User };
diff --git a/src/components/Layout/Header/Header.test.js b/src/components/Layout/Header/Header.test.js
new file mode 100644
index 000000000..767161594
--- /dev/null
+++ b/src/components/Layout/Header/Header.test.js
@@ -0,0 +1,17 @@
+/* eslint-disable react/jsx-filename-extension */
+import React from 'react';
+import { shallow } from 'enzyme';
+import Header from './Header';
+import { YouTubeProvider } from '../../YouTube/YouTubeProvider';
+
+describe('Header', () => {
+ it('should render Header component correctly', () => {
+ const wrapper = shallow(
+
+
+
+ );
+
+ expect(wrapper).toMatchSnapshot();
+ });
+});
diff --git a/src/components/Layout/Header/__snapshots__/Header.test.js.snap b/src/components/Layout/Header/__snapshots__/Header.test.js.snap
new file mode 100644
index 000000000..e58214ee3
--- /dev/null
+++ b/src/components/Layout/Header/__snapshots__/Header.test.js.snap
@@ -0,0 +1,3 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Header should render Header component correctly 1`] = `ShallowWrapper {}`;
diff --git a/src/components/Layout/Header/index.js b/src/components/Layout/Header/index.js
new file mode 100644
index 000000000..579f1ac23
--- /dev/null
+++ b/src/components/Layout/Header/index.js
@@ -0,0 +1 @@
+export { default } from './Header';
diff --git a/src/components/Layout/Layout.component.jsx b/src/components/Layout/Layout.component.jsx
index b82ea3517..3726a7fe0 100644
--- a/src/components/Layout/Layout.component.jsx
+++ b/src/components/Layout/Layout.component.jsx
@@ -1,9 +1,16 @@
import React from 'react';
-
-import './Layout.styles.css';
+import Header from './Header';
+import { Content, MainContainer } from './Layout.styled';
function Layout({ children }) {
- return {children};
+ return (
+ <>
+
+
+ {children}
+
+ >
+ );
}
export default Layout;
diff --git a/src/components/Layout/Layout.styled.js b/src/components/Layout/Layout.styled.js
new file mode 100644
index 000000000..1dcb0aae9
--- /dev/null
+++ b/src/components/Layout/Layout.styled.js
@@ -0,0 +1,20 @@
+import styled from 'styled-components';
+
+const MainContainer = styled.div`
+ display: flex;
+ flex-direction: column;
+ height: 100vh;
+ ${({ theme }) => (theme.secondary ? `background-color: ${theme.secondary}` : '')};
+ ${({ theme }) => (theme.color ? `color: ${theme.color}` : '')};
+`;
+
+const Content = styled.div`
+ display: flex;
+ flex: 1;
+ flex-direction: column;
+ justify-content: flex-start;
+ align-items: stretch;
+ overflow-y: scroll;
+`;
+
+export { MainContainer, Content };
diff --git a/src/components/Layout/Layout.styles.css b/src/components/Layout/Layout.styles.css
deleted file mode 100644
index e873b7c07..000000000
--- a/src/components/Layout/Layout.styles.css
+++ /dev/null
@@ -1,9 +0,0 @@
-.container {
- width: 100vw;
- height: 100vh;
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- margin-top: -3rem;
-}
diff --git a/src/components/Layout/Layout.test.js b/src/components/Layout/Layout.test.js
new file mode 100644
index 000000000..fc8a8d9e9
--- /dev/null
+++ b/src/components/Layout/Layout.test.js
@@ -0,0 +1,17 @@
+/* eslint-disable react/jsx-filename-extension */
+import React from 'react';
+import { shallow } from 'enzyme';
+import Layout from './Layout.component';
+import { YouTubeProvider } from '../YouTube/YouTubeProvider';
+
+describe('Layout', () => {
+ it('should render Layout component correctly', () => {
+ const wrapper = shallow(
+
+
+
+ );
+
+ expect(wrapper).toMatchSnapshot();
+ });
+});
diff --git a/src/components/Layout/__snapshots__/Layout.test.js.snap b/src/components/Layout/__snapshots__/Layout.test.js.snap
new file mode 100644
index 000000000..8155a5ee5
--- /dev/null
+++ b/src/components/Layout/__snapshots__/Layout.test.js.snap
@@ -0,0 +1,3 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Layout should render Layout component correctly 1`] = `ShallowWrapper {}`;
diff --git a/src/components/YouTube/Detail/RelatedVideos.jsx b/src/components/YouTube/Detail/RelatedVideos.jsx
new file mode 100644
index 000000000..63f72fd80
--- /dev/null
+++ b/src/components/YouTube/Detail/RelatedVideos.jsx
@@ -0,0 +1,54 @@
+import React from 'react';
+
+import { useHistory } from 'react-router';
+import {
+ RelatedVideosContainer,
+ VideoItem,
+ VideoPreview,
+ VideoTitle,
+ VideoDescription,
+ VideoTitleDescWrap,
+} from './VideoDetail.styled';
+
+import useVideos from '../useVideos';
+import useFavorites from '../../FavoritesButton/useFavorites';
+
+const RelatedVideos = ({ relatedTo }) => {
+ const history = useHistory();
+ const { favorites } = useFavorites();
+
+ const { isLoading, error, videos } = useVideos({
+ relatedToVideoId: relatedTo?.id?.videoId,
+ favoriteIds: history.location.pathname.startsWith('/favorites')
+ ? favorites
+ : undefined,
+ });
+
+ if (isLoading) return
Loading...
;
+
+ return (
+
+ {error && Error. Displaying mock data...
}
+ {videos.map((video) => (
+ {
+ history.push(
+ history.location.pathname.startsWith('/favorites')
+ ? `/favorites/${video.id}`
+ : `/${video.id.videoId}`
+ );
+ }}
+ >
+
+
+ {video.snippet.title}
+ {video.snippet.description}
+
+
+ ))}
+
+ );
+};
+
+export default RelatedVideos;
diff --git a/src/components/YouTube/Detail/VideoDetail.jsx b/src/components/YouTube/Detail/VideoDetail.jsx
new file mode 100644
index 000000000..505557254
--- /dev/null
+++ b/src/components/YouTube/Detail/VideoDetail.jsx
@@ -0,0 +1,56 @@
+import React from 'react';
+import { useParams } from 'react-router';
+
+import {
+ Container,
+ Row,
+ VideoPlayer,
+ Col,
+ VideoInfo,
+ Title,
+ Description,
+ ColGrow,
+ FavoritesButtonWrapper,
+} from './VideoDetail.styled';
+import useVideo from '../useVideo';
+import RelatedVideos from './RelatedVideos';
+import FavoritesButton from '../../FavoritesButton/FavoritesButton';
+import { useAuth } from '../../../providers/Auth';
+
+const VideoDetail = () => {
+ const { id } = useParams();
+ const { video } = useVideo(id);
+ const { authenticated } = useAuth();
+
+ return (
+ event.stopPropagation()}>
+
+
+
+ {authenticated && (
+
+
+
+ )}
+
+ {video?.snippet?.title}
+ {video?.snippet?.description}
+
+
+
+
+
+
+
+ );
+};
+
+export default VideoDetail;
diff --git a/src/components/YouTube/Detail/VideoDetail.styled.js b/src/components/YouTube/Detail/VideoDetail.styled.js
new file mode 100644
index 000000000..9fc0c9331
--- /dev/null
+++ b/src/components/YouTube/Detail/VideoDetail.styled.js
@@ -0,0 +1,101 @@
+import styled from 'styled-components';
+
+const Container = styled.div`
+ display: flex;
+ flex-direction: column;
+ width: 100%;
+ max-width: 1200px;
+ background-color: white;
+ padding: 20px;
+ align-self: center;
+ ${({ theme }) => (theme.primary ? `border-color: ${theme.primary}` : '')};
+ ${({ theme }) => (theme.primary ? `background: darkgray` : '')};
+`;
+
+const Row = styled.div`
+ display: flex;
+ flex-direction: row;
+ flex: 1;
+ /* height: 90vh; */
+`;
+
+const Col = styled.div`
+ display: flex;
+ flex-direction: column;
+ flex: 0;
+`;
+
+const ColGrow = styled(Col)`
+ flex: 1;
+`;
+
+const VideoPlayer = styled.iframe``;
+
+const VideoInfo = styled(Col)``;
+
+const Title = styled.h2`
+ font-size: 15px;
+ margin: 0;
+ margin-left: 5px;
+`;
+
+const Description = styled.p`
+ font-size: 13px;
+ margin: 0;
+ margin-left: 5px;
+`;
+
+const RelatedVideosContainer = styled(Col)`
+ padding: 5px;
+`;
+
+const VideoItem = styled(Row)`
+ border-top: 1px solid lightgray;
+ height: 75px;
+ padding: 5px;
+ &:hover {
+ background: lightgray;
+ ${({ theme }) => (theme.secondary ? `background-color: ${theme.secondary}` : '')};
+ ${({ theme }) => (theme.color ? `color: ${theme.color}` : '')};
+ }
+`;
+
+const VideoPreview = styled.img``;
+
+const VideoTitleDescWrap = styled(ColGrow)`
+ overflow: hidden;
+`;
+
+const VideoTitle = styled.h2`
+ font-size: 13px;
+ margin: 5px 0;
+ padding-left: 5px;
+`;
+
+const VideoDescription = styled.p`
+ font-size: 11px;
+ margin: 0;
+ padding-left: 5px;
+`;
+
+const FavoritesButtonWrapper = styled.div`
+ margin-left: 5px;
+`;
+
+export {
+ Container,
+ Row,
+ Col,
+ ColGrow,
+ VideoPlayer,
+ VideoInfo,
+ Title,
+ Description,
+ RelatedVideosContainer,
+ VideoItem,
+ VideoTitleDescWrap,
+ VideoPreview,
+ VideoTitle,
+ VideoDescription,
+ FavoritesButtonWrapper,
+};
diff --git a/src/components/YouTube/List/VideoList.jsx b/src/components/YouTube/List/VideoList.jsx
new file mode 100644
index 000000000..b32af95c8
--- /dev/null
+++ b/src/components/YouTube/List/VideoList.jsx
@@ -0,0 +1,62 @@
+import React from 'react';
+import { useHistory } from 'react-router-dom';
+import useVideos from '../useVideos';
+
+import {
+ VideosContainer,
+ VideoCard,
+ VideoPreview,
+ VideoDescription,
+ VideoTitle,
+ VideoContent,
+} from './VideoList.styled';
+import { useYouTube } from '../YouTubeProvider';
+import useFavorites from '../../FavoritesButton/useFavorites';
+
+const VideoList = () => {
+ const history = useHistory();
+ const { state } = useYouTube();
+ const { search } = state;
+
+ const { favorites } = useFavorites();
+ const { videos, isLoading, error } = useVideos({
+ search,
+ favoriteIds: history.location.pathname.startsWith('/favorites')
+ ? favorites
+ : undefined,
+ });
+
+ if (isLoading) return Loading...
;
+
+ return (
+ <>
+ {error && (
+
+ Error from YouTube API, displaying mock data...
+
+ )}
+
+ {videos.map((item) => (
+ {
+ history.push(
+ history.location.pathname.startsWith('/favorites')
+ ? `/favorites/${item.id}`
+ : `/${item.id.videoId}`
+ );
+ }}
+ >
+
+
+ {item.snippet.title}
+ {item.snippet.description}
+
+
+ ))}
+
+ >
+ );
+};
+
+export default VideoList;
diff --git a/src/components/YouTube/List/VideoList.styled.js b/src/components/YouTube/List/VideoList.styled.js
new file mode 100644
index 000000000..b5a2ebfd2
--- /dev/null
+++ b/src/components/YouTube/List/VideoList.styled.js
@@ -0,0 +1,46 @@
+import styled from 'styled-components';
+
+const VideosContainer = styled.div`
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: center;
+ align-self: center;
+ max-width: 1400px;
+`;
+
+const VideoCard = styled.div`
+ display: flex;
+ flex-direction: column;
+ width: 250px;
+ margin: 10px;
+ border: 1px solid lightgray;
+ &:hover {
+ background: lightgray;
+ ${({ theme }) => (theme.primary ? `background-color: ${theme.primary}` : '')};
+ }
+`;
+
+const VideoPreview = styled.img``;
+
+const VideoContent = styled.div`
+ padding: 10px;
+`;
+
+const VideoTitle = styled.h2`
+ font-size: 15px;
+ margin: 5px 0;
+`;
+
+const VideoDescription = styled.p`
+ font-size: 11px;
+ margin: 0;
+`;
+
+export {
+ VideosContainer,
+ VideoCard,
+ VideoPreview,
+ VideoContent,
+ VideoTitle,
+ VideoDescription,
+};
diff --git a/src/components/YouTube/List/VideoList.test.js b/src/components/YouTube/List/VideoList.test.js
new file mode 100644
index 000000000..7974fcc1a
--- /dev/null
+++ b/src/components/YouTube/List/VideoList.test.js
@@ -0,0 +1,25 @@
+/* eslint-disable react/jsx-filename-extension */
+import React from 'react';
+import { shallow } from 'enzyme';
+
+import VideoList from './VideoList';
+import mockData from './youtube-videos-mock.json';
+import { YouTubeProvider } from '../YouTubeProvider';
+
+describe('VideoList', () => {
+ let props;
+ beforeEach(() => {
+ props = {
+ videos: mockData.items,
+ };
+ });
+ it('should render VideoList component correctly', () => {
+ const wrapper = shallow(
+
+
+
+ );
+
+ expect(wrapper).toMatchSnapshot();
+ });
+});
diff --git a/src/components/YouTube/List/__snapshots__/VideoList.test.js.snap b/src/components/YouTube/List/__snapshots__/VideoList.test.js.snap
new file mode 100644
index 000000000..f519fbc88
--- /dev/null
+++ b/src/components/YouTube/List/__snapshots__/VideoList.test.js.snap
@@ -0,0 +1,3 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`VideoList should render VideoList component correctly 1`] = `ShallowWrapper {}`;
diff --git a/src/components/YouTube/List/youtube-videos-mock.json b/src/components/YouTube/List/youtube-videos-mock.json
new file mode 100644
index 000000000..df27886cb
--- /dev/null
+++ b/src/components/YouTube/List/youtube-videos-mock.json
@@ -0,0 +1,828 @@
+{
+ "kind": "youtube#searchListResponse",
+ "etag": "LRviZfd_p3HDDD2uBk5Qv7zaEQU",
+ "nextPageToken": "CBkQAA",
+ "regionCode": "MX",
+ "pageInfo": {
+ "totalResults": 2323,
+ "resultsPerPage": 25
+ },
+ "items": [
+ {
+ "kind": "youtube#searchResult",
+ "etag": "erqeM78PZDWIBe8qOGHGM2WdSE8",
+ "id": {
+ "kind": "youtube#video",
+ "videoId": "nmXMgqjQzls"
+ },
+ "snippet": {
+ "publishedAt": "2019-09-30T23:54:32Z",
+ "channelId": "UCPGzT4wecuWM0BH9mPiulXg",
+ "title": "Video Tour | Welcome to Wizeline Guadalajara",
+ "description": "Follow Hector Padilla, Wizeline Director of Engineering, for a lively tour of our office. In 2018, Wizeline opened its stunning new office in Guadalajara, Jalisco, ...",
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/nmXMgqjQzls/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/nmXMgqjQzls/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/nmXMgqjQzls/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ },
+ "channelTitle": "Wizeline",
+ "liveBroadcastContent": "none",
+ "publishTime": "2019-09-30T23:54:32Z"
+ }
+ },
+ {
+ "kind": "youtube#searchResult",
+ "etag": "7VY0u60YdqamyHOCAufd7r6qTsQ",
+ "id": {
+ "kind": "youtube#video",
+ "videoId": "HYyRZiwBWc8"
+ },
+ "snippet": {
+ "publishedAt": "2019-04-18T18:48:04Z",
+ "channelId": "UCPGzT4wecuWM0BH9mPiulXg",
+ "title": "Wizeline Guadalajara | Bringing Silicon Valley to Mexico",
+ "description": "Wizeline continues to offer a Silicon Valley culture in burgeoning innovation hubs like Mexico and Vietnam. In 2018, our Guadalajara team moved into a ...",
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/HYyRZiwBWc8/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/HYyRZiwBWc8/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/HYyRZiwBWc8/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ },
+ "channelTitle": "Wizeline",
+ "liveBroadcastContent": "none",
+ "publishTime": "2019-04-18T18:48:04Z"
+ }
+ },
+ {
+ "kind": "youtube#searchResult",
+ "etag": "by0t_nrT2TB-IQkQpgSWUVUwpKI",
+ "id": {
+ "kind": "youtube#video",
+ "videoId": "Po3VwR_NNGk"
+ },
+ "snippet": {
+ "publishedAt": "2019-03-05T03:52:55Z",
+ "channelId": "UCXmAOGwFYxIq5qrScJeeV4g",
+ "title": "Wizeline hace sentir a empleados como en casa",
+ "description": "En el 2014, Bismarck fundó Wizeline, compañía tecnológica que trabaja con los corporativos ofreciendo una plataforma para que desarrollen software de forma ...",
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/Po3VwR_NNGk/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/Po3VwR_NNGk/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/Po3VwR_NNGk/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ },
+ "channelTitle": "El Economista TV",
+ "liveBroadcastContent": "none",
+ "publishTime": "2019-03-05T03:52:55Z"
+ }
+ },
+ {
+ "kind": "youtube#searchResult",
+ "etag": "9-Ag8hUNYBLTjuli6eECa5GXV1Y",
+ "id": {
+ "kind": "youtube#video",
+ "videoId": "7PtYNO6g7eI"
+ },
+ "snippet": {
+ "publishedAt": "2019-04-12T20:00:45Z",
+ "channelId": "UCPGzT4wecuWM0BH9mPiulXg",
+ "title": "We Are Wizeline",
+ "description": "Engineering a better tomorrow. Wizeline is a global software development company that helps its clients solve their biggest challenges with design and ...",
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/7PtYNO6g7eI/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/7PtYNO6g7eI/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/7PtYNO6g7eI/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ },
+ "channelTitle": "Wizeline",
+ "liveBroadcastContent": "none",
+ "publishTime": "2019-04-12T20:00:45Z"
+ }
+ },
+ {
+ "kind": "youtube#searchResult",
+ "etag": "pVQGVs72zHvpgl0ewNKX2DTOH6w",
+ "id": {
+ "kind": "youtube#video",
+ "videoId": "YuW0CE_8i1I"
+ },
+ "snippet": {
+ "publishedAt": "2018-12-13T21:51:39Z",
+ "channelId": "UCPGzT4wecuWM0BH9mPiulXg",
+ "title": "Wizeline Thrives in Mexico City",
+ "description": "Our vibrant Mexico City office is home to agile software engineers, talented UX designers, and brilliant data scientists. Learn about the rich history of Mexico City.",
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/YuW0CE_8i1I/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/YuW0CE_8i1I/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/YuW0CE_8i1I/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ },
+ "channelTitle": "Wizeline",
+ "liveBroadcastContent": "none",
+ "publishTime": "2018-12-13T21:51:39Z"
+ }
+ },
+ {
+ "kind": "youtube#searchResult",
+ "etag": "HlSqzTYW4HGFDNAOPCs6nIRXdq8",
+ "id": {
+ "kind": "youtube#video",
+ "videoId": "CHzlSGRvWPs"
+ },
+ "snippet": {
+ "publishedAt": "2017-03-08T22:41:43Z",
+ "channelId": "UCUsm-fannqOY02PNN67C0KA",
+ "title": "Wizeline",
+ "description": "El plan de Wizeline, una empresa de inteligencia artificial, para ayudar a crecer la comunidad de ciencia de datos en CDMX y todo el país, a través de cursos ...",
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/CHzlSGRvWPs/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/CHzlSGRvWPs/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/CHzlSGRvWPs/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ },
+ "channelTitle": "Noticieros Televisa",
+ "liveBroadcastContent": "none",
+ "publishTime": "2017-03-08T22:41:43Z"
+ }
+ },
+ {
+ "kind": "youtube#searchResult",
+ "etag": "S1Ewc2IMjGC1VE5mH3AryZ43IPQ",
+ "id": {
+ "kind": "youtube#video",
+ "videoId": "cjO2fJy8asM"
+ },
+ "snippet": {
+ "publishedAt": "2018-09-25T17:45:19Z",
+ "channelId": "UCPGzT4wecuWM0BH9mPiulXg",
+ "title": "A Day in the Life of an Engineering Manager at Wizeline",
+ "description": "Fernando Espinoza shares his experience working as an engineering manager at Wizeline and mentoring other engineers. Learn about Fernando's passions ...",
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/cjO2fJy8asM/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/cjO2fJy8asM/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/cjO2fJy8asM/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ },
+ "channelTitle": "Wizeline",
+ "liveBroadcastContent": "none",
+ "publishTime": "2018-09-25T17:45:19Z"
+ }
+ },
+ {
+ "kind": "youtube#searchResult",
+ "etag": "jZZv6Ufu43kg1KzFlBOWDVKfPkY",
+ "id": {
+ "kind": "youtube#video",
+ "videoId": "zClI9OjgKXM"
+ },
+ "snippet": {
+ "publishedAt": "2020-04-24T20:22:17Z",
+ "channelId": "UCPGzT4wecuWM0BH9mPiulXg",
+ "title": "Wizeline Technical Writing Academy | Featuring Eduardo Ocejo",
+ "description": "",
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/zClI9OjgKXM/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/zClI9OjgKXM/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/zClI9OjgKXM/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ },
+ "channelTitle": "Wizeline",
+ "liveBroadcastContent": "none",
+ "publishTime": "2020-04-24T20:22:17Z"
+ }
+ },
+ {
+ "kind": "youtube#searchResult",
+ "etag": "z5o2tIUROuWNZU5-1pzMPjoqQC8",
+ "id": {
+ "kind": "youtube#video",
+ "videoId": "8bz9R61oY5o"
+ },
+ "snippet": {
+ "publishedAt": "2019-09-26T15:28:46Z",
+ "channelId": "UCUP6qv-_EIL0hwTsJaKYnvw",
+ "title": "Silicon Valley en México",
+ "description": "Empresas de Silicon Valley buscan establecerse en México por el gran talento que hay en nuestro país. Es una investigación de Roberto Domínguez.",
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/8bz9R61oY5o/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/8bz9R61oY5o/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/8bz9R61oY5o/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ },
+ "channelTitle": "Azteca Noticias",
+ "liveBroadcastContent": "none",
+ "publishTime": "2019-09-26T15:28:46Z"
+ }
+ },
+ {
+ "kind": "youtube#searchResult",
+ "etag": "Q4bqsw7kAYe6PV1sh494TQ-UJ8c",
+ "id": {
+ "kind": "youtube#video",
+ "videoId": "7dJFraOqcoQ"
+ },
+ "snippet": {
+ "publishedAt": "2019-07-02T17:40:20Z",
+ "channelId": "UCPGzT4wecuWM0BH9mPiulXg",
+ "title": "Why Wizeline? featuring Juan Pablo Villa in Mexico City",
+ "description": "Juan Pablo, known as Gianpa at Wizeline, is a software engineer in our Mexico City office. Gianpa focuses on Android apps, is an integral part of our culture, ...",
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/7dJFraOqcoQ/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/7dJFraOqcoQ/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/7dJFraOqcoQ/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ },
+ "channelTitle": "Wizeline",
+ "liveBroadcastContent": "none",
+ "publishTime": "2019-07-02T17:40:20Z"
+ }
+ },
+ {
+ "kind": "youtube#searchResult",
+ "etag": "cXSMV8jX2lv1ue3UUnbW3xCmIU4",
+ "id": {
+ "kind": "youtube#video",
+ "videoId": "w-Qwc_XJrWc"
+ },
+ "snippet": {
+ "publishedAt": "2020-12-31T16:26:44Z",
+ "channelId": "UCPGzT4wecuWM0BH9mPiulXg",
+ "title": "Wizeline's 2020 Year in Review",
+ "description": "There's no doubt that 2020 has been an unprecedented year. However, amidst all the chaos, we achieved remarkable growth in various areas of our business.",
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/w-Qwc_XJrWc/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/w-Qwc_XJrWc/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/w-Qwc_XJrWc/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ },
+ "channelTitle": "Wizeline",
+ "liveBroadcastContent": "none",
+ "publishTime": "2020-12-31T16:26:44Z"
+ }
+ },
+ {
+ "kind": "youtube#searchResult",
+ "etag": "j9q9-dcRhTRDr0MCkJUMKdYt7u8",
+ "id": {
+ "kind": "youtube#video",
+ "videoId": "rjir_cHTl5w"
+ },
+ "snippet": {
+ "publishedAt": "2019-04-29T20:37:26Z",
+ "channelId": "UCPGzT4wecuWM0BH9mPiulXg",
+ "title": "Why Wizeline? featuring Hugo Lopez in Mexico City",
+ "description": "",
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/rjir_cHTl5w/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/rjir_cHTl5w/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/rjir_cHTl5w/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ },
+ "channelTitle": "Wizeline",
+ "liveBroadcastContent": "none",
+ "publishTime": "2019-04-29T20:37:26Z"
+ }
+ },
+ {
+ "kind": "youtube#searchResult",
+ "etag": "MYfT5K8aZNvalrm2RR_HtylFffc",
+ "id": {
+ "kind": "youtube#video",
+ "videoId": "DcFK1x3NHGY"
+ },
+ "snippet": {
+ "publishedAt": "2016-09-01T18:02:11Z",
+ "channelId": "UCPGzT4wecuWM0BH9mPiulXg",
+ "title": "Why Wizeline? (We're Hiring in Mexico!)",
+ "description": "A quick look at why people join Wizeline, what motivates us as a team and what it's like to work in our Guadalajara office. Learn more and apply here: ...",
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/DcFK1x3NHGY/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/DcFK1x3NHGY/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/DcFK1x3NHGY/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ },
+ "channelTitle": "Wizeline",
+ "liveBroadcastContent": "none",
+ "publishTime": "2016-09-01T18:02:11Z"
+ }
+ },
+ {
+ "kind": "youtube#searchResult",
+ "etag": "8dssV5QkZWEMmoo4DIq0k27aoIg",
+ "id": {
+ "kind": "youtube#video",
+ "videoId": "3BzYWAqZgFw"
+ },
+ "snippet": {
+ "publishedAt": "2019-07-02T17:45:28Z",
+ "channelId": "UCPGzT4wecuWM0BH9mPiulXg",
+ "title": "Why Wizeline? featuring Oswaldo Herrera in Mexico City",
+ "description": "Oswaldo is a software engineering in Wizeline's Mexico City office. He joined Wizeline because of the camaraderie and deep sense of commitment of our teams.",
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/3BzYWAqZgFw/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/3BzYWAqZgFw/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/3BzYWAqZgFw/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ },
+ "channelTitle": "Wizeline",
+ "liveBroadcastContent": "none",
+ "publishTime": "2019-07-02T17:45:28Z"
+ }
+ },
+ {
+ "kind": "youtube#searchResult",
+ "etag": "FMbfPlflDyPx4UgcA42igb97xlk",
+ "id": {
+ "kind": "youtube#video",
+ "videoId": "3KVFmT-Tp2w"
+ },
+ "snippet": {
+ "publishedAt": "2019-02-11T17:55:19Z",
+ "channelId": "UCd6MoB9NC6uYN2grvUNT-Zg",
+ "title": "Caso de Éxito AWS: Wizeline [Spanish]",
+ "description": "Central de socios de APN - https://amzn.to/2S7tIXM Fundada en 2014, Wizeline es una compañía joven e innovadora que nació en la nube para ofrecer soporte ...",
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/3KVFmT-Tp2w/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/3KVFmT-Tp2w/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/3KVFmT-Tp2w/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ },
+ "channelTitle": "Amazon Web Services",
+ "liveBroadcastContent": "none",
+ "publishTime": "2019-02-11T17:55:19Z"
+ }
+ },
+ {
+ "kind": "youtube#searchResult",
+ "etag": "0ww3Jk-j4d4TMsFNL213EhE0gGg",
+ "id": {
+ "kind": "youtube#video",
+ "videoId": "aKuPmY2m1Ro"
+ },
+ "snippet": {
+ "publishedAt": "2019-12-27T20:47:29Z",
+ "channelId": "UCPGzT4wecuWM0BH9mPiulXg",
+ "title": "Wizeline's 2019 Year in Review",
+ "description": "",
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/aKuPmY2m1Ro/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/aKuPmY2m1Ro/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/aKuPmY2m1Ro/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ },
+ "channelTitle": "Wizeline",
+ "liveBroadcastContent": "none",
+ "publishTime": "2019-12-27T20:47:29Z"
+ }
+ },
+ {
+ "kind": "youtube#searchResult",
+ "etag": "8q-ajUMnXZm4gQzfSIiyrG2tA7A",
+ "id": {
+ "kind": "youtube#video",
+ "videoId": "24sTHUyWhRM"
+ },
+ "snippet": {
+ "publishedAt": "2016-10-05T00:03:32Z",
+ "channelId": "UCPGzT4wecuWM0BH9mPiulXg",
+ "title": "[1 of 2] Wizeline CEO shares career lessons from Google",
+ "description": "Founder & CEO Bismarck Lepe on growth opportunities at Wizeline and his career-path experience as an early Google employee. Join our team!",
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/24sTHUyWhRM/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/24sTHUyWhRM/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/24sTHUyWhRM/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ },
+ "channelTitle": "Wizeline",
+ "liveBroadcastContent": "none",
+ "publishTime": "2016-10-05T00:03:32Z"
+ }
+ },
+ {
+ "kind": "youtube#searchResult",
+ "etag": "4QA9Eisz9-HncD9EENUm0LV7hXI",
+ "id": {
+ "kind": "youtube#video",
+ "videoId": "IxGc1gSqB3A"
+ },
+ "snippet": {
+ "publishedAt": "2021-02-04T17:45:11Z",
+ "channelId": "UCPGzT4wecuWM0BH9mPiulXg",
+ "title": "Wizeline Data Engineering featuring Tania Reyes",
+ "description": "Tania discovered her interest in Big Data while working at Wizeline and took Wizeline Academy courses to skill up and join the data team. Now, she works on ...",
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/IxGc1gSqB3A/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/IxGc1gSqB3A/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/IxGc1gSqB3A/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ },
+ "channelTitle": "Wizeline",
+ "liveBroadcastContent": "none",
+ "publishTime": "2021-02-04T17:45:11Z"
+ }
+ },
+ {
+ "kind": "youtube#searchResult",
+ "etag": "5_OftJlDpcfykudIpO7nn92Pq6s",
+ "id": {
+ "kind": "youtube#video",
+ "videoId": "NP1gAnbeNno"
+ },
+ "snippet": {
+ "publishedAt": "2019-11-12T20:45:18Z",
+ "channelId": "UCPGzT4wecuWM0BH9mPiulXg",
+ "title": "Wizeline Querétaro | Mexico's New Knowledge Economy (We're hiring!)",
+ "description": "A small but mighty (and growing) team, the Queretaro crew has taken ownership of growing the office and brand, speaking at university events, hosting tech ...",
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/NP1gAnbeNno/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/NP1gAnbeNno/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/NP1gAnbeNno/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ },
+ "channelTitle": "Wizeline",
+ "liveBroadcastContent": "none",
+ "publishTime": "2019-11-12T20:45:18Z"
+ }
+ },
+ {
+ "kind": "youtube#searchResult",
+ "etag": "0XmhUGwmJNRilJR1S6VgOmdO9ho",
+ "id": {
+ "kind": "youtube#video",
+ "videoId": "F6Krwu6lUc8"
+ },
+ "snippet": {
+ "publishedAt": "2020-10-23T04:15:31Z",
+ "channelId": "UCPGzT4wecuWM0BH9mPiulXg",
+ "title": "Miriam Godinez | Women in Leadership at Wizeline",
+ "description": "Science and technology always caught Miriam's attention. One of her ultimate goals as a Senior Engineer Manager and Lead from the Mobile Team at Wizeline ...",
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/F6Krwu6lUc8/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/F6Krwu6lUc8/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/F6Krwu6lUc8/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ },
+ "channelTitle": "Wizeline",
+ "liveBroadcastContent": "none",
+ "publishTime": "2020-10-23T04:15:31Z"
+ }
+ },
+ {
+ "kind": "youtube#searchResult",
+ "etag": "mM9qAwvNhFKGUv6mCIamuWVo0NE",
+ "id": {
+ "kind": "youtube#video",
+ "videoId": "RFq7gfvhtCk"
+ },
+ "snippet": {
+ "publishedAt": "2020-05-23T00:11:23Z",
+ "channelId": "UCPGzT4wecuWM0BH9mPiulXg",
+ "title": "Welcome Back to Wizeline Vietnam | Extended Version",
+ "description": "Thanks to swift government action, the COVID-19 situation in Vietnam has reached a point where businesses are able to return to work and reopen offices.",
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/RFq7gfvhtCk/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/RFq7gfvhtCk/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/RFq7gfvhtCk/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ },
+ "channelTitle": "Wizeline",
+ "liveBroadcastContent": "none",
+ "publishTime": "2020-05-23T00:11:23Z"
+ }
+ },
+ {
+ "kind": "youtube#searchResult",
+ "etag": "sVz5aNJZHehOf7qJCTLOLh1V40M",
+ "id": {
+ "kind": "youtube#video",
+ "videoId": "E1Vq_A3WKK8"
+ },
+ "snippet": {
+ "publishedAt": "2017-12-09T18:46:07Z",
+ "channelId": "UCPGzT4wecuWM0BH9mPiulXg",
+ "title": "How does Wizeline work?",
+ "description": "Wizeline builds teams with a mix of technical and non-technical talent to deliver better products, faster. Learn more about our consulting services: ...",
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/E1Vq_A3WKK8/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/E1Vq_A3WKK8/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/E1Vq_A3WKK8/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ },
+ "channelTitle": "Wizeline",
+ "liveBroadcastContent": "none",
+ "publishTime": "2017-12-09T18:46:07Z"
+ }
+ },
+ {
+ "kind": "youtube#searchResult",
+ "etag": "kiG9Z-CXE-mbZVBeom4qLurWb4w",
+ "id": {
+ "kind": "youtube#video",
+ "videoId": "ZmkslANDz0Q"
+ },
+ "snippet": {
+ "publishedAt": "2019-12-18T19:22:44Z",
+ "channelId": "UCPGzT4wecuWM0BH9mPiulXg",
+ "title": "12 Wishes from Wizeline | Happy Holidays 2019",
+ "description": "",
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/ZmkslANDz0Q/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/ZmkslANDz0Q/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/ZmkslANDz0Q/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ },
+ "channelTitle": "Wizeline",
+ "liveBroadcastContent": "none",
+ "publishTime": "2019-12-18T19:22:44Z"
+ }
+ },
+ {
+ "kind": "youtube#searchResult",
+ "etag": "bzZZYb96wT_IQHNp5sXm3VDUbXA",
+ "id": {
+ "kind": "youtube#video",
+ "videoId": "Nss3EmTDD3s"
+ },
+ "snippet": {
+ "publishedAt": "2017-12-08T18:13:27Z",
+ "channelId": "UCPGzT4wecuWM0BH9mPiulXg",
+ "title": "Why Wizeline?",
+ "description": "Hear from our employees directly about what excites them about their roles here at Wizeline. Wizeline wants to hire the best and the brightest to accelerate their ...",
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/Nss3EmTDD3s/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/Nss3EmTDD3s/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/Nss3EmTDD3s/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ },
+ "channelTitle": "Wizeline",
+ "liveBroadcastContent": "none",
+ "publishTime": "2017-12-08T18:13:27Z"
+ }
+ }
+ ]
+}
diff --git a/src/components/YouTube/YouTubeProvider.jsx b/src/components/YouTube/YouTubeProvider.jsx
new file mode 100644
index 000000000..8abd23498
--- /dev/null
+++ b/src/components/YouTube/YouTubeProvider.jsx
@@ -0,0 +1,40 @@
+import React, { useContext, useReducer } from 'react';
+
+const YoutTubeContext = React.createContext();
+
+function youtubeReducer(state, action) {
+ switch (action.type) {
+ case 'search':
+ return {
+ ...state,
+ search: action.payload,
+ };
+ case 'switchTheme':
+ return {
+ ...state,
+ theme: state.theme === 'dark' ? 'default' : 'dark',
+ };
+ default: {
+ return state;
+ }
+ }
+}
+
+function YouTubeProvider({ children }) {
+ const [state, dispatch] = useReducer(youtubeReducer, {});
+ return (
+
+ {children}
+
+ );
+}
+
+function useYouTube() {
+ const context = useContext(YoutTubeContext);
+ if (context === undefined) {
+ throw new Error('useYouTube must be used within YouTubeProvider');
+ }
+ return context;
+}
+
+export { YouTubeProvider, useYouTube };
diff --git a/src/components/YouTube/useVideo.js b/src/components/YouTube/useVideo.js
new file mode 100644
index 000000000..e4d87596b
--- /dev/null
+++ b/src/components/YouTube/useVideo.js
@@ -0,0 +1,41 @@
+import { useEffect, useState } from 'react';
+
+import mockData from './List/youtube-videos-mock.json';
+
+function useVideo(id) {
+ const [video, setVideo] = useState();
+ const [isLoading, setLoading] = useState(false);
+ const [error, setError] = useState(null);
+
+ useEffect(() => {
+ if (!id) return;
+ async function fetchVideo() {
+ try {
+ setLoading(true);
+ const url = ['https://www.googleapis.com/youtube/v3/videos?'];
+ url.push(`key=${process.env.REACT_APP_YOUTUBE_API_KEY}`);
+ url.push(`&part=snippet&type=video`);
+ url.push(`&id=${id}`);
+
+ const response = await fetch(url.join(''));
+ const json = await response.json();
+ if (json.error && json.error.code === 403) {
+ setVideo(mockData.items.find((item) => item.id.videoId === id));
+ setError('Error from YouTube API, displaying mock data..');
+ console.error(json);
+ } else {
+ setVideo(json.items);
+ }
+ } catch (err) {
+ setError(err);
+ } finally {
+ setLoading(false);
+ }
+ }
+ fetchVideo();
+ }, [id]);
+
+ return { video, isLoading, error };
+}
+
+export default useVideo;
diff --git a/src/components/YouTube/useVideos.js b/src/components/YouTube/useVideos.js
new file mode 100644
index 000000000..137a6d021
--- /dev/null
+++ b/src/components/YouTube/useVideos.js
@@ -0,0 +1,52 @@
+import { useEffect, useState } from 'react';
+
+import mockData from './List/youtube-videos-mock.json';
+
+function useVideos({ search, favoriteIds, relatedToVideoId }) {
+ const [videos, setVideos] = useState([]);
+ const [isLoading, setLoading] = useState(false);
+ const [error, setError] = useState(null);
+
+ useEffect(() => {
+ async function fetchVideos() {
+ try {
+ const url = [
+ favoriteIds
+ ? 'https://www.googleapis.com/youtube/v3/videos?'
+ : 'https://www.googleapis.com/youtube/v3/search?',
+ ];
+ url.push(`key=${process.env.REACT_APP_YOUTUBE_API_KEY}`);
+ url.push(`&part=snippet&maxResults=10&type=video`);
+ if (search) url.push(`&q=${search}`);
+ if (favoriteIds) url.push(`&id=${favoriteIds.join(',')}`);
+ if (relatedToVideoId && !favoriteIds)
+ url.push(`&relatedToVideoId=${relatedToVideoId}`);
+
+ setLoading(true);
+ const response = await fetch(url.join(''));
+ const json = await response.json();
+ if (json.error && json.error.code === 403) {
+ setVideos(
+ favoriteIds
+ ? mockData.items.filter((item) => favoriteIds.includes(item.id.videoId))
+ : mockData.items
+ );
+ setError('Error from YouTube API, displaying mock data..');
+ console.error(json);
+ } else {
+ setVideos(json.items);
+ }
+ } catch (err) {
+ setError(err);
+ } finally {
+ setLoading(false);
+ }
+ }
+
+ fetchVideos();
+ }, [search, favoriteIds, relatedToVideoId]);
+
+ return { videos, isLoading, error };
+}
+
+export default useVideos;
diff --git a/src/global.css b/src/global.css
index 4feb3c75e..3df5b755b 100644
--- a/src/global.css
+++ b/src/global.css
@@ -3,51 +3,7 @@ html {
line-height: 1.6;
font-weight: 400;
font-family: sans-serif;
- box-sizing: border-box;
scroll-behavior: smooth;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
-}
-
-*,
-*::before,
-*::after {
- box-sizing: inherit;
-}
-
-body {
- margin: 0;
- padding: 0;
- text-rendering: optimizeLegibility;
- background-image: linear-gradient(
- 120deg,
- #eea2a2 0,
- #bbc1bf 19%,
- #57c6e1 42%,
- #b49fda 79%,
- #7ac5d8 100%
- );
- background-size: 400% 400%;
- background-position: var(--bg-position);
- transition: background-position 2s ease;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
-}
-
-.separator::before {
- content: '•';
- color: white;
- padding: 0.4rem;
-}
-
-a {
- text-decoration: none;
- font-weight: bold;
- color: white;
-}
-
-a:active {
- color: blueviolet;
-}
-
-hr {
+ overflow: hidden;
}
diff --git a/src/index.js b/src/index.js
index b93eaa337..85ae52f85 100644
--- a/src/index.js
+++ b/src/index.js
@@ -2,11 +2,8 @@ import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/App';
+import 'sanitize.css';
import './global.css';
-ReactDOM.render(
-
-
- ,
- document.getElementById('root')
-);
+const app = React.createElement(App);
+ReactDOM.render(app, document.getElementById('root'));
diff --git a/src/pages/Home/Home.page.jsx b/src/pages/Home/Home.page.jsx
deleted file mode 100644
index 08d1dd5c0..000000000
--- a/src/pages/Home/Home.page.jsx
+++ /dev/null
@@ -1,39 +0,0 @@
-import React, { useRef } from 'react';
-import { Link, useHistory } from 'react-router-dom';
-
-import { useAuth } from '../../providers/Auth';
-import './Home.styles.css';
-
-function HomePage() {
- const history = useHistory();
- const sectionRef = useRef(null);
- const { authenticated, logout } = useAuth();
-
- function deAuthenticate(event) {
- event.preventDefault();
- logout();
- history.push('/');
- }
-
- return (
-
- Hello stranger!
- {authenticated ? (
- <>
- Good to have you back
-
-
- ← logout
-
-
- show me something cool →
-
- >
- ) : (
- let me in →
- )}
-
- );
-}
-
-export default HomePage;
diff --git a/src/pages/Home/Home.styles.css b/src/pages/Home/Home.styles.css
deleted file mode 100644
index 5e0a702c3..000000000
--- a/src/pages/Home/Home.styles.css
+++ /dev/null
@@ -1,8 +0,0 @@
-.homepage {
- text-align: center;
-}
-
-.homepage h1 {
- font-size: 3rem;
- letter-spacing: -2px;
-}
diff --git a/src/pages/Home/index.js b/src/pages/Home/index.js
deleted file mode 100644
index e288d0036..000000000
--- a/src/pages/Home/index.js
+++ /dev/null
@@ -1 +0,0 @@
-export { default } from './Home.page';
diff --git a/src/pages/Login/Login.page.jsx b/src/pages/Login/Login.page.jsx
index 89367f276..1317a6710 100644
--- a/src/pages/Login/Login.page.jsx
+++ b/src/pages/Login/Login.page.jsx
@@ -1,38 +1,61 @@
-import React from 'react';
-import { useHistory } from 'react-router';
+import React, { useState } from 'react';
import { useAuth } from '../../providers/Auth';
-import './Login.styles.css';
+import { Container, ErrorLabel } from './Login.page.styled';
function LoginPage() {
const { login } = useAuth();
- const history = useHistory();
+ const [values, setValues] = useState({});
+ const [error, setError] = useState();
- function authenticate(event) {
+ const authenticate = async (event) => {
event.preventDefault();
- login();
- history.push('/secret');
- }
+ try {
+ setError(undefined);
+ await login(values);
+ } catch (err) {
+ setError(err);
+ }
+ };
+
+ const handleInputChange = (event) => {
+ const newValues = { ...values };
+ newValues[event.target.id] = event.target.value;
+ setValues(newValues);
+ };
return (
-
+ {error && Username or password incorrect!}
+
);
}
diff --git a/src/pages/Login/Login.page.styled.jsx b/src/pages/Login/Login.page.styled.jsx
new file mode 100644
index 000000000..c60f55a72
--- /dev/null
+++ b/src/pages/Login/Login.page.styled.jsx
@@ -0,0 +1,17 @@
+import styled from 'styled-components';
+
+const Container = styled.div`
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-start;
+ align-items: center;
+ flex: 1;
+ margin-top: 5%;
+`;
+
+const ErrorLabel = styled.p`
+ font-size: 15px;
+ color: red;
+`;
+
+export { Container, ErrorLabel };
diff --git a/src/pages/Login/Login.styles.css b/src/pages/Login/Login.styles.css
deleted file mode 100644
index d4cfdde73..000000000
--- a/src/pages/Login/Login.styles.css
+++ /dev/null
@@ -1,47 +0,0 @@
-.login {
- width: 300px;
-}
-
-.login h1 {
- text-align: center;
- letter-spacing: -1px;
-}
-
-.login-form {
- display: flex;
- flex-direction: column;
- align-items: center;
-}
-
-.form-group {
- width: 100%;
- display: flex;
- flex-direction: column;
- margin-bottom: 1rem;
-}
-
-.form-group strong {
- display: block;
- font-weight: 700;
- text-transform: capitalize;
- margin-bottom: 0.4rem;
-}
-
-.form-group input {
- color: white;
- font-size: 1.2rem;
- width: 100%;
- padding: 0.4rem 0.6rem;
- border-radius: 3px;
- border: 1px solid white;
- background-color: rgba(0, 0, 0, 0.1);
-}
-
-.login-form button[type='submit'] {
- width: 5rem;
- margin-top: 1rem;
- padding: 0.4rem 0.6rem;
- font-size: 1.2rem;
- border: none;
- border-radius: 3px;
-}
diff --git a/src/pages/Secret/Secret.page.jsx b/src/pages/Secret/Secret.page.jsx
deleted file mode 100644
index bb9df9b2d..000000000
--- a/src/pages/Secret/Secret.page.jsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import React from 'react';
-import { Link } from 'react-router-dom';
-
-function SecretPage() {
- return (
-
-
- welcome, voyager...
- ← go back
-
-
-
- );
-}
-
-export default SecretPage;
diff --git a/src/pages/Secret/index.js b/src/pages/Secret/index.js
deleted file mode 100644
index 894d9a95f..000000000
--- a/src/pages/Secret/index.js
+++ /dev/null
@@ -1 +0,0 @@
-export { default } from './Secret.page';
diff --git a/src/providers/Auth/Auth.provider.jsx b/src/providers/Auth/Auth.provider.jsx
index b47385253..fdbb17bac 100644
--- a/src/providers/Auth/Auth.provider.jsx
+++ b/src/providers/Auth/Auth.provider.jsx
@@ -3,6 +3,8 @@ import React, { useState, useEffect, useContext, useCallback } from 'react';
import { AUTH_STORAGE_KEY } from '../../utils/constants';
import { storage } from '../../utils/storage';
+import loginApi from './login.mock';
+
const AuthContext = React.createContext(null);
function useAuth() {
@@ -23,16 +25,22 @@ function AuthProvider({ children }) {
setAuthenticated(isAuthenticated);
}, []);
- const login = useCallback(() => {
- setAuthenticated(true);
- storage.set(AUTH_STORAGE_KEY, true);
- }, []);
-
const logout = useCallback(() => {
setAuthenticated(false);
storage.set(AUTH_STORAGE_KEY, false);
}, []);
+ const login = async (values) => {
+ try {
+ await loginApi(values.username, values.password);
+ setAuthenticated(true);
+ storage.set(AUTH_STORAGE_KEY, true);
+ } catch (err) {
+ logout();
+ throw err;
+ }
+ };
+
return (
{children}
diff --git a/src/providers/Auth/login.mock.js b/src/providers/Auth/login.mock.js
new file mode 100644
index 000000000..ca9bf0f37
--- /dev/null
+++ b/src/providers/Auth/login.mock.js
@@ -0,0 +1,17 @@
+const mockedUser = {
+ id: '123',
+ name: 'Wizeline',
+ avatarUrl:
+ 'https://media.glassdoor.com/sqll/868055/wizeline-squarelogo-1473976610815.png',
+};
+
+export default async function loginApi(username, password) {
+ return new Promise((resolve, reject) => {
+ setTimeout(() => {
+ if (username === 'wizeline' && password === 'Rocks!') {
+ return resolve(mockedUser);
+ }
+ return reject(new Error('Username or password invalid'));
+ }, 500);
+ });
+}
diff --git a/src/setupTests.js b/src/setupTests.js
index 74b1a275a..f2f13b357 100644
--- a/src/setupTests.js
+++ b/src/setupTests.js
@@ -3,3 +3,8 @@
// expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom/extend-expect';
+
+import Enzyme from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+
+Enzyme.configure({ adapter: new Adapter() });
diff --git a/src/utils/hooks/useFortune.js b/src/utils/hooks/useFortune.js
deleted file mode 100644
index b6f572a07..000000000
--- a/src/utils/hooks/useFortune.js
+++ /dev/null
@@ -1,31 +0,0 @@
-import { useState, useEffect } from 'react';
-
-import { random } from '../fns';
-
-const API_URL = 'http://fortunecookieapi.herokuapp.com/v1/fortunes?limit=10';
-
-function useFortune() {
- const [fortune, setFortune] = useState(null);
-
- useEffect(() => {
- async function findMyFortune() {
- try {
- const response = await fetch(API_URL);
- const fortuneCookies = await response.json();
-
- const randomIndex = random(fortuneCookies.length);
- const currentFortune = fortuneCookies[randomIndex];
-
- setFortune(currentFortune.message);
- } catch (error) {
- console.error('Bad fortune: ', error);
- }
- }
-
- findMyFortune();
- }, []);
-
- return { fortune };
-}
-
-export { useFortune };
diff --git a/src/utils/useLocalStorage.js b/src/utils/useLocalStorage.js
new file mode 100644
index 000000000..a51ff485c
--- /dev/null
+++ b/src/utils/useLocalStorage.js
@@ -0,0 +1,63 @@
+/**
+ * By Alfredo Pacheco
+ * alfredo.pacheco@wizeline.com
+ * j.alfredo.pacheco@gmail.com
+ *
+ * Using localStorage thru react-query
+ */
+import { useMutation, useQuery, useQueryClient } from 'react-query';
+
+const useLocalStorageMutation = ({ cacheKey }) => {
+ const queryClient = useQueryClient();
+
+ return useMutation(
+ (newValue) => {
+ localStorage.setItem(cacheKey, JSON.stringify(newValue));
+ return newValue;
+ },
+ {
+ onMutate: async (newValue) => {
+ // Cancel any outgoing refetches (so they don't overwrite our optimistic update)
+ await queryClient.cancelQueries(cacheKey);
+
+ // Snapshot the previous value
+ const previousValue = queryClient.getQueryData(cacheKey);
+
+ // Optimistically update to the new value
+ queryClient.setQueryData(cacheKey, () => newValue);
+
+ // Return a context object with the snapshotted value
+ return { previousValue, newValue };
+ },
+ onError: (err, newValue, context) => {
+ queryClient.setQueryData(cacheKey, context.previousValue);
+ },
+ onSettled: () => {
+ queryClient.invalidateQueries(cacheKey);
+ },
+ }
+ );
+};
+
+const useLocalStorage = ({ cacheKey, initialData }) => {
+ const mutation = useLocalStorageMutation({ cacheKey });
+
+ return {
+ ...useQuery(
+ cacheKey,
+ () => {
+ const value = localStorage.getItem(cacheKey);
+ if (value) return JSON.parse(value);
+ mutation.mutate(initialData);
+ return initialData;
+ },
+ {
+ retry: 1,
+ initialData,
+ }
+ ),
+ mutation,
+ };
+};
+
+export { useLocalStorage, useLocalStorageMutation };
diff --git a/yarn.lock b/yarn.lock
index 0530c750a..9b9367286 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -16,6 +16,13 @@
dependencies:
"@babel/highlight" "^7.10.4"
+"@babel/code-frame@^7.12.13":
+ 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.12.13"
+
"@babel/compat-data@^7.10.4", "@babel/compat-data@^7.11.0", "@babel/compat-data@^7.9.0":
version "7.11.0"
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.11.0.tgz#e9f73efe09af1355b723a7f39b11bad637d7c99c"
@@ -78,6 +85,22 @@
jsesc "^2.5.1"
source-map "^0.6.1"
+"@babel/generator@^7.12.17":
+ version "7.12.17"
+ resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.17.tgz#9ef1dd792d778b32284411df63f4f668a9957287"
+ integrity sha512-DSA7ruZrY4WI8VxuS1jWSRezFnghEoYEFrZcw9BizQRmOZiUsiHl59+qEARGPqPikwA/GPTyRCi7isuCK/oyqg==
+ dependencies:
+ "@babel/types" "^7.12.17"
+ jsesc "^2.5.1"
+ source-map "^0.5.0"
+
+"@babel/helper-annotate-as-pure@^7.0.0":
+ 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.13"
+
"@babel/helper-annotate-as-pure@^7.10.4":
version "7.10.4"
resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz#5bf0d495a3f757ac3bda48b5bf3b3ba309c72ba3"
@@ -167,6 +190,15 @@
"@babel/template" "^7.10.4"
"@babel/types" "^7.10.4"
+"@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/helper-get-function-arity" "^7.12.13"
+ "@babel/template" "^7.12.13"
+ "@babel/types" "^7.12.13"
+
"@babel/helper-get-function-arity@^7.10.4":
version "7.10.4"
resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz#98c1cbea0e2332f33f9a4661b8ce1505b2c19ba2"
@@ -174,6 +206,13 @@
dependencies:
"@babel/types" "^7.10.4"
+"@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/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"
@@ -188,6 +227,13 @@
dependencies:
"@babel/types" "^7.11.0"
+"@babel/helper-module-imports@^7.0.0":
+ 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.13"
+
"@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.8.3":
version "7.10.4"
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz#4c5c54be04bd31670a7382797d75b9fa2e5b5620"
@@ -269,11 +315,23 @@
dependencies:
"@babel/types" "^7.11.0"
+"@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.13"
+
"@babel/helper-validator-identifier@^7.10.4":
version "7.10.4"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz#a78c7a7251e01f616512d31b10adcf52ada5e0d2"
integrity sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==
+"@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==
+
"@babel/helper-wrap-function@^7.10.4":
version "7.10.4"
resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.10.4.tgz#8a6f701eab0ff39f765b5a1cfef409990e624b87"
@@ -302,11 +360,25 @@
chalk "^2.0.0"
js-tokens "^4.0.0"
+"@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.12.11"
+ chalk "^2.0.0"
+ js-tokens "^4.0.0"
+
"@babel/parser@^7.1.0", "@babel/parser@^7.10.4", "@babel/parser@^7.11.5", "@babel/parser@^7.4.3", "@babel/parser@^7.7.0", "@babel/parser@^7.9.0":
version "7.11.5"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.5.tgz#c7ff6303df71080ec7a4f5b8c003c58f1cf51037"
integrity sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q==
+"@babel/parser@^7.12.13", "@babel/parser@^7.12.17":
+ version "7.12.17"
+ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.17.tgz#bc85d2d47db38094e5bb268fc761716e7d693848"
+ integrity sha512-r1yKkiUTYMQ8LiEI0UcQx5ETw5dpTLn9wijn9hk6KkTtOK95FndDN10M+8/s6k/Ymlbivw0Av9q4SlgF80PtHg==
+
"@babel/plugin-proposal-async-generator-functions@^7.10.4", "@babel/plugin-proposal-async-generator-functions@^7.8.3":
version "7.10.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.5.tgz#3491cabf2f7c179ab820606cec27fed15e0e8558"
@@ -1115,6 +1187,13 @@
dependencies:
regenerator-runtime "^0.13.4"
+"@babel/runtime@^7.12.5", "@babel/runtime@^7.6.2":
+ version "7.13.10"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.13.10.tgz#47d42a57b6095f4468da440388fdbad8bebf0d7d"
+ integrity sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw==
+ dependencies:
+ regenerator-runtime "^0.13.4"
+
"@babel/template@^7.10.4", "@babel/template@^7.4.0", "@babel/template@^7.8.6":
version "7.10.4"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.4.tgz#3251996c4200ebc71d1a8fc405fba940f36ba278"
@@ -1124,6 +1203,15 @@
"@babel/parser" "^7.10.4"
"@babel/types" "^7.10.4"
+"@babel/template@^7.12.13":
+ 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.10.4", "@babel/traverse@^7.11.5", "@babel/traverse@^7.4.3", "@babel/traverse@^7.7.0", "@babel/traverse@^7.9.0":
version "7.11.5"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.11.5.tgz#be777b93b518eb6d76ee2e1ea1d143daa11e61c3"
@@ -1139,6 +1227,21 @@
globals "^11.1.0"
lodash "^4.17.19"
+"@babel/traverse@^7.4.5":
+ version "7.12.17"
+ resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.17.tgz#40ec8c7ffb502c4e54c7f95492dc11b88d718619"
+ integrity sha512-LGkTqDqdiwC6Q7fWSwQoas/oyiEYw6Hqjve5KOSykXkmFJFqzvGMb9niaUEag3Rlve492Mkye3gLw9FTv94fdQ==
+ dependencies:
+ "@babel/code-frame" "^7.12.13"
+ "@babel/generator" "^7.12.17"
+ "@babel/helper-function-name" "^7.12.13"
+ "@babel/helper-split-export-declaration" "^7.12.13"
+ "@babel/parser" "^7.12.17"
+ "@babel/types" "^7.12.17"
+ 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.11.0", "@babel/types@^7.11.5", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.7.0", "@babel/types@^7.9.0":
version "7.11.5"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.11.5.tgz#d9de577d01252d77c6800cee039ee64faf75662d"
@@ -1148,6 +1251,15 @@
lodash "^4.17.19"
to-fast-properties "^2.0.0"
+"@babel/types@^7.12.13", "@babel/types@^7.12.17":
+ version "7.12.17"
+ resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.17.tgz#9d711eb807e0934c90b8b1ca0eb1f7230d150963"
+ integrity sha512-tNMDjcv/4DIcHxErTgwB9q2ZcYyN0sUfgGKUK/mm1FJK7Wz+KstoEekxrl/tBiNDgLK1HGi+sppj1An/1DR4fQ==
+ dependencies:
+ "@babel/helper-validator-identifier" "^7.12.11"
+ lodash "^4.17.19"
+ to-fast-properties "^2.0.0"
+
"@cnakazawa/watch@^1.0.3":
version "1.0.4"
resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a"
@@ -1166,6 +1278,28 @@
resolved "https://registry.yarnpkg.com/@csstools/normalize.css/-/normalize.css-10.1.0.tgz#f0950bba18819512d42f7197e56c518aa491cf18"
integrity sha512-ij4wRiunFfaJxjB0BdrYHIH8FxBJpOwNPhhAcunlmPdXudL1WQV1qoP9un6JsEBAgQH+7UXyyjh0g7jTxXK6tg==
+"@emotion/is-prop-valid@^0.8.8":
+ version "0.8.8"
+ resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a"
+ integrity sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==
+ dependencies:
+ "@emotion/memoize" "0.7.4"
+
+"@emotion/memoize@0.7.4":
+ version "0.7.4"
+ resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb"
+ integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==
+
+"@emotion/stylis@^0.8.4":
+ version "0.8.5"
+ resolved "https://registry.yarnpkg.com/@emotion/stylis/-/stylis-0.8.5.tgz#deacb389bd6ee77d1e7fcaccce9e16c5c7e78e04"
+ integrity sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==
+
+"@emotion/unitless@^0.7.4":
+ version "0.7.5"
+ resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.5.tgz#77211291c1900a700b8a78cfafda3160d76949ed"
+ integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==
+
"@hapi/address@2.x.x":
version "2.1.4"
resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5"
@@ -1944,6 +2078,21 @@ aggregate-error@^3.0.0:
clean-stack "^2.0.0"
indent-string "^4.0.0"
+airbnb-prop-types@^2.16.0:
+ version "2.16.0"
+ resolved "https://registry.yarnpkg.com/airbnb-prop-types/-/airbnb-prop-types-2.16.0.tgz#b96274cefa1abb14f623f804173ee97c13971dc2"
+ integrity sha512-7WHOFolP/6cS96PhKNrslCLMYAI8yB1Pp6u6XmxozQOiZbsI5ycglZr5cHhBFfuRcQQjzCMith5ZPZdYiJCxUg==
+ dependencies:
+ array.prototype.find "^2.1.1"
+ function.prototype.name "^1.1.2"
+ is-regex "^1.1.0"
+ object-is "^1.1.2"
+ object.assign "^4.1.0"
+ object.entries "^1.1.2"
+ prop-types "^15.7.2"
+ prop-types-exact "^1.2.0"
+ react-is "^16.13.1"
+
ajv-errors@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d"
@@ -2110,6 +2259,11 @@ array-equal@^1.0.0:
resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93"
integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=
+array-filter@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-1.0.0.tgz#baf79e62e6ef4c2a4c0b831232daffec251f9d83"
+ integrity sha1-uveeYubvTCpMC4MSMtr/7CUfnYM=
+
array-flatten@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
@@ -2151,6 +2305,14 @@ array-unique@^0.3.2:
resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428"
integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=
+array.prototype.find@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/array.prototype.find/-/array.prototype.find-2.1.1.tgz#3baca26108ca7affb08db06bf0be6cb3115a969c"
+ integrity sha512-mi+MYNJYLTx2eNYy+Yh6raoQacCsNeeMUaspFPh9Y141lFSsWxxB8V9mM2ye+eqiRs917J6/pJ4M9ZPzenWckA==
+ dependencies:
+ define-properties "^1.1.3"
+ es-abstract "^1.17.4"
+
array.prototype.flat@^1.2.1, array.prototype.flat@^1.2.3:
version "1.2.3"
resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz#0de82b426b0318dbfdb940089e38b043d37f6c7b"
@@ -2390,6 +2552,21 @@ babel-plugin-named-asset-import@^0.3.6:
resolved "https://registry.yarnpkg.com/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.6.tgz#c9750a1b38d85112c9e166bf3ef7c5dbc605f4be"
integrity sha512-1aGDUfL1qOOIoqk9QKGIo2lANk+C7ko/fqH0uIyC71x3PEGz0uVP8ISgfEsFuG+FKmjHTvFK/nNM8dowpmUxLA==
+"babel-plugin-styled-components@>= 1":
+ version "1.12.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-styled-components/-/babel-plugin-styled-components-1.12.0.tgz#1dec1676512177de6b827211e9eda5a30db4f9b9"
+ integrity sha512-FEiD7l5ZABdJPpLssKXjBUJMYqzbcNzBowfXDCdJhOpbhWiewapUaY+LZGT8R4Jg2TwOjGjG4RKeyrO5p9sBkA==
+ dependencies:
+ "@babel/helper-annotate-as-pure" "^7.0.0"
+ "@babel/helper-module-imports" "^7.0.0"
+ babel-plugin-syntax-jsx "^6.18.0"
+ lodash "^4.17.11"
+
+babel-plugin-syntax-jsx@^6.18.0:
+ version "6.18.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946"
+ integrity sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=
+
babel-plugin-syntax-object-rest-spread@^6.8.0:
version "6.13.0"
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5"
@@ -2485,6 +2662,11 @@ bcrypt-pbkdf@^1.0.0:
dependencies:
tweetnacl "^0.14.3"
+big-integer@^1.6.16:
+ version "1.6.48"
+ resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.48.tgz#8fd88bd1632cba4a1c8c3e3d7159f08bb95b4b9e"
+ integrity sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w==
+
big.js@^5.2.2:
version "5.2.2"
resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328"
@@ -2586,6 +2768,19 @@ braces@^3.0.1, braces@~3.0.2:
dependencies:
fill-range "^7.0.1"
+broadcast-channel@^3.4.1:
+ version "3.5.3"
+ resolved "https://registry.yarnpkg.com/broadcast-channel/-/broadcast-channel-3.5.3.tgz#c75c39d923ae8af6284a893bfdc8bd3996d2dd2d"
+ integrity sha512-OLOXfwReZa2AAAh9yOUyiALB3YxBe0QpThwwuyRHLgpl8bSznSDmV6Mz7LeBJg1VZsMcDcNMy7B53w12qHrIhQ==
+ dependencies:
+ "@babel/runtime" "^7.7.2"
+ detect-node "^2.0.4"
+ js-sha3 "0.8.0"
+ microseconds "0.2.0"
+ nano-time "1.0.0"
+ rimraf "3.0.2"
+ unload "2.2.0"
+
brorand@^1.0.1:
version "1.1.0"
resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
@@ -2790,6 +2985,14 @@ cache-base@^1.0.1:
union-value "^1.0.0"
unset-value "^1.0.0"
+call-bind@^1.0.0, call-bind@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c"
+ integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==
+ dependencies:
+ function-bind "^1.1.1"
+ get-intrinsic "^1.0.2"
+
call-me-maybe@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b"
@@ -2837,6 +3040,11 @@ camelcase@5.3.1, camelcase@^5.0.0, camelcase@^5.3.1:
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
+camelize@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.0.tgz#164a5483e630fa4321e5af07020e531831b2609b"
+ integrity sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=
+
caniuse-api@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0"
@@ -2910,6 +3118,30 @@ chardet@^0.7.0:
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==
+cheerio-select-tmp@^0.1.0:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/cheerio-select-tmp/-/cheerio-select-tmp-0.1.1.tgz#55bbef02a4771710195ad736d5e346763ca4e646"
+ integrity sha512-YYs5JvbpU19VYJyj+F7oYrIE2BOll1/hRU7rEy/5+v9BzkSo3bK81iAeeQEMI92vRIxz677m72UmJUiVwwgjfQ==
+ dependencies:
+ css-select "^3.1.2"
+ css-what "^4.0.0"
+ domelementtype "^2.1.0"
+ domhandler "^4.0.0"
+ domutils "^2.4.4"
+
+cheerio@^1.0.0-rc.3:
+ version "1.0.0-rc.5"
+ resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.5.tgz#88907e1828674e8f9fee375188b27dadd4f0fa2f"
+ integrity sha512-yoqps/VCaZgN4pfXtenwHROTp8NG6/Hlt4Jpz2FEP0ZJQ+ZUkVDd0hAPDNKhj3nakpfPt/CNs57yEtxD1bXQiw==
+ dependencies:
+ cheerio-select-tmp "^0.1.0"
+ dom-serializer "~1.2.0"
+ domhandler "^4.0.0"
+ entities "~2.1.0"
+ htmlparser2 "^6.0.0"
+ parse5 "^6.0.0"
+ parse5-htmlparser2-tree-adapter "^6.0.0"
+
chokidar@^2.1.8:
version "2.1.8"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917"
@@ -3119,7 +3351,7 @@ combined-stream@^1.0.6, combined-stream@~1.0.6:
dependencies:
delayed-stream "~1.0.0"
-commander@^2.11.0, commander@^2.20.0:
+commander@^2.11.0, commander@^2.19.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==
@@ -3416,6 +3648,11 @@ css-blank-pseudo@^0.1.4:
dependencies:
postcss "^7.0.5"
+css-color-keywords@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/css-color-keywords/-/css-color-keywords-1.0.0.tgz#fea2616dc676b2962686b3af8dbdbe180b244e05"
+ integrity sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=
+
css-color-names@0.0.4, css-color-names@^0.0.4:
version "0.0.4"
resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0"
@@ -3487,6 +3724,26 @@ css-select@^2.0.0:
domutils "^1.7.0"
nth-check "^1.0.2"
+css-select@^3.1.2:
+ version "3.1.2"
+ resolved "https://registry.yarnpkg.com/css-select/-/css-select-3.1.2.tgz#d52cbdc6fee379fba97fb0d3925abbd18af2d9d8"
+ integrity sha512-qmss1EihSuBNWNNhHjxzxSfJoFBM/lERB/Q4EnsJQQC62R2evJDW481091oAdOr9uh46/0n4nrg0It5cAnj1RA==
+ dependencies:
+ boolbase "^1.0.0"
+ css-what "^4.0.0"
+ domhandler "^4.0.0"
+ domutils "^2.4.3"
+ nth-check "^2.0.0"
+
+css-to-react-native@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/css-to-react-native/-/css-to-react-native-3.0.0.tgz#62dbe678072a824a689bcfee011fc96e02a7d756"
+ integrity sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ==
+ dependencies:
+ camelize "^1.0.0"
+ css-color-keywords "^1.0.0"
+ postcss-value-parser "^4.0.2"
+
css-tree@1.0.0-alpha.37:
version "1.0.0-alpha.37"
resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.37.tgz#98bebd62c4c1d9f960ec340cf9f7522e30709a22"
@@ -3513,6 +3770,11 @@ css-what@^3.2.1:
resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.3.0.tgz#10fec696a9ece2e591ac772d759aacabac38cd39"
integrity sha512-pv9JPyatiPaQ6pf4OvD/dbfm0o5LviWmwxNWzblYf/1u9QZd0ihV+PMwy5jdQWQ3349kZmKEx9WXuSka2dM4cg==
+css-what@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/css-what/-/css-what-4.0.0.tgz#35e73761cab2eeb3d3661126b23d7aa0e8432233"
+ integrity sha512-teijzG7kwYfNVsUh2H/YN62xW3KK9YhXEgSlbxMlcyjPNvdKJqFx5lrwlJgoFP1ZHlB89iGDlo/JyshKeRhv5A==
+
css.escape@^1.5.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb"
@@ -3844,6 +4106,11 @@ dir-glob@2.0.0:
arrify "^1.0.1"
path-type "^3.0.0"
+discontinuous-range@1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/discontinuous-range/-/discontinuous-range-1.0.0.tgz#e38331f0844bba49b9a9cb71c771585aab1bc65a"
+ integrity sha1-44Mx8IRLukm5qctxx3FYWqsbxlo=
+
dns-equal@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d"
@@ -3906,6 +4173,15 @@ dom-serializer@0:
domelementtype "^2.0.1"
entities "^2.0.0"
+dom-serializer@^1.0.1, dom-serializer@~1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.2.0.tgz#3433d9136aeb3c627981daa385fc7f32d27c48f1"
+ integrity sha512-n6kZFH/KlCrqs/1GHMOd5i2fd/beQHuehKdWvNNffbGHTr/almdhuVvTVFb3V7fglz+nC50fFusu3lY33h12pA==
+ dependencies:
+ domelementtype "^2.0.1"
+ domhandler "^4.0.0"
+ entities "^2.0.0"
+
domain-browser@^1.1.1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda"
@@ -3921,6 +4197,11 @@ domelementtype@^2.0.1:
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.0.1.tgz#1f8bdfe91f5a78063274e803b4bdcedf6e94f94d"
integrity sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==
+domelementtype@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.1.0.tgz#a851c080a6d1c3d94344aed151d99f669edf585e"
+ integrity sha512-LsTgx/L5VpD+Q8lmsXSHW2WpA+eBlZ9HPf3erD1IoPF00/3JKHZ3BknUVA2QGDNu69ZNmyFmCWBSO45XjYKC5w==
+
domexception@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90"
@@ -3935,6 +4216,13 @@ domhandler@^2.3.0:
dependencies:
domelementtype "1"
+domhandler@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.0.0.tgz#01ea7821de996d85f69029e81fa873c21833098e"
+ integrity sha512-KPTbnGQ1JeEMQyO1iYXoagsI6so/C96HZiFyByU3T6iAzpXn8EGEvct6unm1ZGoed8ByO2oirxgwxBmqKF9haA==
+ dependencies:
+ domelementtype "^2.1.0"
+
domutils@1.5.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf"
@@ -3951,6 +4239,15 @@ domutils@^1.5.1, domutils@^1.7.0:
dom-serializer "0"
domelementtype "1"
+domutils@^2.4.3, domutils@^2.4.4:
+ version "2.4.4"
+ resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.4.4.tgz#282739c4b150d022d34699797369aad8d19bbbd3"
+ integrity sha512-jBC0vOsECI4OMdD0GC9mGn7NXPLb+Qt6KW1YDQzeQYRUFKmNG8lh7mO5HiELfr+lLQE7loDVI4QcAxV80HS+RA==
+ dependencies:
+ dom-serializer "^1.0.1"
+ domelementtype "^2.0.1"
+ domhandler "^4.0.0"
+
dot-case@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.3.tgz#21d3b52efaaba2ea5fda875bb1aa8124521cf4aa"
@@ -4085,6 +4382,75 @@ entities@^2.0.0:
resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.3.tgz#5c487e5742ab93c15abb5da22759b8590ec03b7f"
integrity sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==
+entities@~2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/entities/-/entities-2.1.0.tgz#992d3129cf7df6870b96c57858c249a120f8b8b5"
+ integrity sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==
+
+enzyme-adapter-react-16@^1.15.6:
+ version "1.15.6"
+ resolved "https://registry.yarnpkg.com/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.15.6.tgz#fd677a658d62661ac5afd7f7f541f141f8085901"
+ integrity sha512-yFlVJCXh8T+mcQo8M6my9sPgeGzj85HSHi6Apgf1Cvq/7EL/J9+1JoJmJsRxZgyTvPMAqOEpRSu/Ii/ZpyOk0g==
+ dependencies:
+ enzyme-adapter-utils "^1.14.0"
+ enzyme-shallow-equal "^1.0.4"
+ has "^1.0.3"
+ object.assign "^4.1.2"
+ object.values "^1.1.2"
+ prop-types "^15.7.2"
+ react-is "^16.13.1"
+ react-test-renderer "^16.0.0-0"
+ semver "^5.7.0"
+
+enzyme-adapter-utils@^1.14.0:
+ version "1.14.0"
+ resolved "https://registry.yarnpkg.com/enzyme-adapter-utils/-/enzyme-adapter-utils-1.14.0.tgz#afbb0485e8033aa50c744efb5f5711e64fbf1ad0"
+ integrity sha512-F/z/7SeLt+reKFcb7597IThpDp0bmzcH1E9Oabqv+o01cID2/YInlqHbFl7HzWBl4h3OdZYedtwNDOmSKkk0bg==
+ dependencies:
+ airbnb-prop-types "^2.16.0"
+ function.prototype.name "^1.1.3"
+ has "^1.0.3"
+ object.assign "^4.1.2"
+ object.fromentries "^2.0.3"
+ prop-types "^15.7.2"
+ semver "^5.7.1"
+
+enzyme-shallow-equal@^1.0.1, enzyme-shallow-equal@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/enzyme-shallow-equal/-/enzyme-shallow-equal-1.0.4.tgz#b9256cb25a5f430f9bfe073a84808c1d74fced2e"
+ integrity sha512-MttIwB8kKxypwHvRynuC3ahyNc+cFbR8mjVIltnmzQ0uKGqmsfO4bfBuLxb0beLNPhjblUEYvEbsg+VSygvF1Q==
+ dependencies:
+ has "^1.0.3"
+ object-is "^1.1.2"
+
+enzyme@^3.11.0:
+ version "3.11.0"
+ resolved "https://registry.yarnpkg.com/enzyme/-/enzyme-3.11.0.tgz#71d680c580fe9349f6f5ac6c775bc3e6b7a79c28"
+ integrity sha512-Dw8/Gs4vRjxY6/6i9wU0V+utmQO9kvh9XLnz3LIudviOnVYDEe2ec+0k+NQoMamn1VrjKgCUOWj5jG/5M5M0Qw==
+ dependencies:
+ array.prototype.flat "^1.2.3"
+ cheerio "^1.0.0-rc.3"
+ enzyme-shallow-equal "^1.0.1"
+ function.prototype.name "^1.1.2"
+ has "^1.0.3"
+ html-element-map "^1.2.0"
+ is-boolean-object "^1.0.1"
+ is-callable "^1.1.5"
+ is-number-object "^1.0.4"
+ is-regex "^1.0.5"
+ is-string "^1.0.5"
+ is-subset "^0.1.1"
+ lodash.escape "^4.0.1"
+ lodash.isequal "^4.5.0"
+ object-inspect "^1.7.0"
+ object-is "^1.0.2"
+ object.assign "^4.1.0"
+ object.entries "^1.1.1"
+ object.values "^1.1.1"
+ raf "^3.4.1"
+ rst-selector-parser "^2.2.3"
+ string.prototype.trim "^1.2.1"
+
errno@^0.1.3, errno@~0.1.7:
version "0.1.7"
resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618"
@@ -4116,6 +4482,23 @@ es-abstract@^1.17.0, es-abstract@^1.17.0-next.1, es-abstract@^1.17.2, es-abstrac
string.prototype.trimend "^1.0.1"
string.prototype.trimstart "^1.0.1"
+es-abstract@^1.17.4:
+ version "1.17.7"
+ resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.7.tgz#a4de61b2f66989fc7421676c1cb9787573ace54c"
+ integrity sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==
+ dependencies:
+ es-to-primitive "^1.2.1"
+ function-bind "^1.1.1"
+ has "^1.0.3"
+ has-symbols "^1.0.1"
+ is-callable "^1.2.2"
+ is-regex "^1.1.1"
+ object-inspect "^1.8.0"
+ object-keys "^1.1.1"
+ object.assign "^4.1.1"
+ string.prototype.trimend "^1.0.1"
+ string.prototype.trimstart "^1.0.1"
+
es-abstract@^1.18.0-next.0:
version "1.18.0-next.0"
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0-next.0.tgz#b302834927e624d8e5837ed48224291f2c66e6fc"
@@ -4134,6 +4517,26 @@ es-abstract@^1.18.0-next.0:
string.prototype.trimend "^1.0.1"
string.prototype.trimstart "^1.0.1"
+es-abstract@^1.18.0-next.1:
+ version "1.18.0-next.2"
+ resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0-next.2.tgz#088101a55f0541f595e7e057199e27ddc8f3a5c2"
+ integrity sha512-Ih4ZMFHEtZupnUh6497zEL4y2+w8+1ljnCyaTa+adcoafI1GOvMwFlDjBLfWR7y9VLfrjRJe9ocuHY1PSR9jjw==
+ dependencies:
+ call-bind "^1.0.2"
+ es-to-primitive "^1.2.1"
+ function-bind "^1.1.1"
+ get-intrinsic "^1.0.2"
+ has "^1.0.3"
+ has-symbols "^1.0.1"
+ is-callable "^1.2.2"
+ is-negative-zero "^2.0.1"
+ is-regex "^1.1.1"
+ object-inspect "^1.9.0"
+ object-keys "^1.1.1"
+ object.assign "^4.1.2"
+ string.prototype.trimend "^1.0.3"
+ string.prototype.trimstart "^1.0.3"
+
es-to-primitive@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a"
@@ -5064,11 +5467,26 @@ function-bind@^1.1.1:
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
+function.prototype.name@^1.1.2, function.prototype.name@^1.1.3:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.3.tgz#0bb034bb308e7682826f215eb6b2ae64918847fe"
+ integrity sha512-H51qkbNSp8mtkJt+nyW1gyStBiKZxfRqySNUR99ylq6BPXHKI4SEvIlTKp4odLfjRKJV04DFWMU3G/YRlQOsag==
+ dependencies:
+ call-bind "^1.0.0"
+ define-properties "^1.1.3"
+ es-abstract "^1.18.0-next.1"
+ functions-have-names "^1.2.1"
+
functional-red-black-tree@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=
+functions-have-names@^1.2.1:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.2.tgz#98d93991c39da9361f8e50b337c4f6e41f120e21"
+ integrity sha512-bLgc3asbWdwPbx2mNk2S49kmJCuQeu0nfmaOgbs8WIyzzkw3r4htszdIi9Q9EMezDPTYuJx2wvjZ/EwgAthpnA==
+
gensync@^1.0.0-beta.1:
version "1.0.0-beta.1"
resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269"
@@ -5079,6 +5497,15 @@ get-caller-file@^2.0.1:
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
+get-intrinsic@^1.0.2:
+ 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"
+ has-symbols "^1.0.1"
+
get-own-enumerable-property-symbols@^3.0.0:
version "3.0.2"
resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664"
@@ -5348,7 +5775,7 @@ hmac-drbg@^1.0.0:
minimalistic-assert "^1.0.0"
minimalistic-crypto-utils "^1.0.1"
-hoist-non-react-statics@^3.1.0:
+hoist-non-react-statics@^3.0.0, hoist-non-react-statics@^3.1.0:
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==
@@ -5385,6 +5812,14 @@ html-comment-regex@^1.1.0:
resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.2.tgz#97d4688aeb5c81886a364faa0cad1dda14d433a7"
integrity sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==
+html-element-map@^1.2.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/html-element-map/-/html-element-map-1.3.0.tgz#fcf226985d7111e6c2b958169312ec750d02f0d3"
+ integrity sha512-AqCt/m9YaiMwaaAyOPdq4Ga0cM+jdDWWGueUMkdROZcTeClaGpN0AQeyGchZhTegQoABmc6+IqH7oCR/8vhQYg==
+ dependencies:
+ array-filter "^1.0.0"
+ call-bind "^1.0.2"
+
html-encoding-sniffer@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8"
@@ -5439,6 +5874,16 @@ htmlparser2@^3.3.0:
inherits "^2.0.1"
readable-stream "^3.1.1"
+htmlparser2@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.0.0.tgz#c2da005030390908ca4c91e5629e418e0665ac01"
+ integrity sha512-numTQtDZMoh78zJpaNdJ9MXb2cv5G3jwUoe3dMQODubZvLoGvTE/Ofp6sHvH8OGKcN/8A47pGLi/k58xHP/Tfw==
+ dependencies:
+ domelementtype "^2.0.1"
+ domhandler "^4.0.0"
+ domutils "^2.4.4"
+ entities "^2.0.0"
+
http-deceiver@^1.2.7:
version "1.2.7"
resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87"
@@ -5802,6 +6247,13 @@ is-binary-path@~2.1.0:
dependencies:
binary-extensions "^2.0.0"
+is-boolean-object@^1.0.1:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.0.tgz#e2aaad3a3a8fca34c28f6eee135b156ed2587ff0"
+ integrity sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA==
+ dependencies:
+ call-bind "^1.0.0"
+
is-buffer@^1.0.2, is-buffer@^1.1.5:
version "1.1.6"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
@@ -5812,6 +6264,11 @@ is-callable@^1.1.4, is-callable@^1.2.0:
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.0.tgz#83336560b54a38e35e3a2df7afd0454d691468bb"
integrity sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==
+is-callable@^1.1.5, is-callable@^1.2.2:
+ version "1.2.3"
+ resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.3.tgz#8b1e0500b73a1d76c70487636f368e519de8db8e"
+ integrity sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==
+
is-ci@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c"
@@ -5929,6 +6386,16 @@ is-negative-zero@^2.0.0:
resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.0.tgz#9553b121b0fac28869da9ed459e20c7543788461"
integrity sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE=
+is-negative-zero@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24"
+ integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==
+
+is-number-object@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.4.tgz#36ac95e741cf18b283fc1ddf5e83da798e3ec197"
+ integrity sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==
+
is-number@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195"
@@ -5989,6 +6456,14 @@ is-regex@^1.0.4, is-regex@^1.1.0, is-regex@^1.1.1:
dependencies:
has-symbols "^1.0.1"
+is-regex@^1.0.5:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.2.tgz#81c8ebde4db142f2cf1c53fc86d6a45788266251"
+ integrity sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==
+ dependencies:
+ call-bind "^1.0.2"
+ has-symbols "^1.0.1"
+
is-regexp@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069"
@@ -6019,6 +6494,11 @@ is-string@^1.0.5:
resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6"
integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==
+is-subset@^0.1.1:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/is-subset/-/is-subset-0.1.1.tgz#8a59117d932de1de00f245fcdd39ce43f1e939a6"
+ integrity sha1-ilkRfZMt4d4A8kX83TnOQ/HpOaY=
+
is-svg@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-3.0.0.tgz#9321dbd29c212e5ca99c4fa9794c714bcafa2f75"
@@ -6534,6 +7014,11 @@ jest@24.9.0:
import-local "^2.0.0"
jest-cli "^24.9.0"
+js-sha3@0.8.0:
+ version "0.8.0"
+ resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840"
+ integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==
+
"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
@@ -6932,6 +7417,21 @@ lodash._reinterpolate@^3.0.0:
resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d"
integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=
+lodash.escape@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-4.0.1.tgz#c9044690c21e04294beaa517712fded1fa88de98"
+ integrity sha1-yQRGkMIeBClL6qUXcS/e0fqI3pg=
+
+lodash.flattendeep@^4.4.0:
+ version "4.4.0"
+ resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2"
+ integrity sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=
+
+lodash.isequal@^4.5.0:
+ version "4.5.0"
+ resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
+ integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA=
+
lodash.memoize@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
@@ -7049,6 +7549,14 @@ map-visit@^1.0.0:
dependencies:
object-visit "^1.0.0"
+match-sorter@^6.0.2:
+ version "6.3.0"
+ resolved "https://registry.yarnpkg.com/match-sorter/-/match-sorter-6.3.0.tgz#454a1b31ed218cddbce6231a0ecb5fdc549fed01"
+ integrity sha512-efYOf/wUpNb8FgNY+cOD2EIJI1S5I7YPKsw0LBp7wqPh5pmMS6i/wr3ZWwfwrAw1NvqTA2KUReVRWDX84lUcOQ==
+ dependencies:
+ "@babel/runtime" "^7.12.5"
+ remove-accents "0.4.2"
+
md5.js@^1.3.4:
version "1.3.5"
resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f"
@@ -7150,6 +7658,11 @@ micromatch@^4.0.2:
braces "^3.0.1"
picomatch "^2.0.5"
+microseconds@0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/microseconds/-/microseconds-0.2.0.tgz#233b25f50c62a65d861f978a4a4f8ec18797dc39"
+ integrity sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA==
+
miller-rabin@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d"
@@ -7297,6 +7810,11 @@ mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.5, mkdirp@~0.5.1:
dependencies:
minimist "^1.2.5"
+moo@^0.5.0:
+ version "0.5.1"
+ resolved "https://registry.yarnpkg.com/moo/-/moo-0.5.1.tgz#7aae7f384b9b09f620b6abf6f74ebbcd1b65dbc4"
+ integrity sha512-I1mnb5xn4fO80BH9BLcF0yLypy2UKl+Cb01Fu0hJRkJjlCRtxZMWkTdAtDd5ZqCOxtCkhmRwyI57vWT+1iZ67w==
+
move-concurrently@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92"
@@ -7363,6 +7881,13 @@ nan@^2.12.1:
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01"
integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==
+nano-time@1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/nano-time/-/nano-time-1.0.0.tgz#b0554f69ad89e22d0907f7a12b0993a5d96137ef"
+ integrity sha1-sFVPaa2J4i0JB/ehKwmTpdlhN+8=
+ dependencies:
+ big-integer "^1.6.16"
+
nanomatch@^1.2.9:
version "1.2.13"
resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119"
@@ -7385,6 +7910,16 @@ natural-compare@^1.4.0:
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
+nearley@^2.7.10:
+ version "2.20.1"
+ resolved "https://registry.yarnpkg.com/nearley/-/nearley-2.20.1.tgz#246cd33eff0d012faf197ff6774d7ac78acdd474"
+ integrity sha512-+Mc8UaAebFzgV+KpI5n7DasuuQCHA89dmwm7JXw3TV43ukfNQ9DnBH3Mdb2g/I4Fdxc26pwimBWvjIw0UAILSQ==
+ dependencies:
+ commander "^2.19.0"
+ moo "^0.5.0"
+ railroad-diagrams "^1.0.0"
+ randexp "0.4.6"
+
negotiator@0.6.2:
version "0.6.2"
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb"
@@ -7536,6 +8071,13 @@ nth-check@^1.0.2, nth-check@~1.0.1:
dependencies:
boolbase "~1.0.0"
+nth-check@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.0.tgz#1bb4f6dac70072fc313e8c9cd1417b5074c0a125"
+ integrity sha512-i4sc/Kj8htBrAiH1viZ0TgU8Y5XqCaV/FziYK6TBczxmeKm3AEFWqqF3195yKudrarqy7Zu80Ra5dobFjn9X/Q==
+ dependencies:
+ boolbase "^1.0.0"
+
num2fraction@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede"
@@ -7575,6 +8117,11 @@ object-inspect@^1.7.0, object-inspect@^1.8.0:
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.8.0.tgz#df807e5ecf53a609cc6bfe93eac3cc7be5b3a9d0"
integrity sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==
+object-inspect@^1.9.0:
+ version "1.9.0"
+ resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.9.0.tgz#c90521d74e1127b67266ded3394ad6116986533a"
+ integrity sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==
+
object-is@^1.0.1:
version "1.1.2"
resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.2.tgz#c5d2e87ff9e119f78b7a088441519e2eec1573b6"
@@ -7583,6 +8130,14 @@ object-is@^1.0.1:
define-properties "^1.1.3"
es-abstract "^1.17.5"
+object-is@^1.0.2, object-is@^1.1.2:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.4.tgz#63d6c83c00a43f4cbc9434eb9757c8a5b8565068"
+ integrity sha512-1ZvAZ4wlF7IyPVOcE1Omikt7UpaFlOQq0HlSti+ZvDH3UiD2brwGMwDbyV43jao2bKJ+4+WdPJHSd7kgzKYVqg==
+ dependencies:
+ call-bind "^1.0.0"
+ define-properties "^1.1.3"
+
object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
@@ -7610,6 +8165,16 @@ object.assign@^4.1.0:
has-symbols "^1.0.0"
object-keys "^1.0.11"
+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==
+ dependencies:
+ call-bind "^1.0.0"
+ define-properties "^1.1.3"
+ has-symbols "^1.0.1"
+ object-keys "^1.1.1"
+
object.entries@^1.1.0, object.entries@^1.1.1, object.entries@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.2.tgz#bc73f00acb6b6bb16c203434b10f9a7e797d3add"
@@ -7629,6 +8194,16 @@ object.fromentries@^2.0.2:
function-bind "^1.1.1"
has "^1.0.3"
+object.fromentries@^2.0.3:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.3.tgz#13cefcffa702dc67750314a3305e8cb3fad1d072"
+ integrity sha512-IDUSMXs6LOSJBWE++L0lzIbSqHl9KDCfff2x/JSEIDtEUavUnyMYC2ZGay/04Zq4UT8lvd4xNhU4/YHKibAOlw==
+ dependencies:
+ call-bind "^1.0.0"
+ define-properties "^1.1.3"
+ es-abstract "^1.18.0-next.1"
+ has "^1.0.3"
+
object.getownpropertydescriptors@^2.0.3, object.getownpropertydescriptors@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz#369bf1f9592d8ab89d712dced5cb81c7c5352649"
@@ -7654,6 +8229,16 @@ object.values@^1.1.0, object.values@^1.1.1:
function-bind "^1.1.1"
has "^1.0.3"
+object.values@^1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.2.tgz#7a2015e06fcb0f546bd652486ce8583a4731c731"
+ integrity sha512-MYC0jvJopr8EK6dPBiO8Nb9mvjdypOachO5REGk6MXzujbBrAisKo3HmdEI6kZDL6fC31Mwee/5YbtMebixeag==
+ dependencies:
+ call-bind "^1.0.0"
+ define-properties "^1.1.3"
+ es-abstract "^1.18.0-next.1"
+ has "^1.0.3"
+
obuf@^1.0.0, obuf@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e"
@@ -7895,6 +8480,13 @@ parse-json@^5.0.0:
json-parse-even-better-errors "^2.3.0"
lines-and-columns "^1.1.6"
+parse5-htmlparser2-tree-adapter@^6.0.0:
+ version "6.0.1"
+ resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz#2cdf9ad823321140370d4dbf5d3e92c7c8ddc6e6"
+ integrity sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==
+ dependencies:
+ parse5 "^6.0.1"
+
parse5@4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608"
@@ -7905,6 +8497,11 @@ parse5@5.1.0:
resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.0.tgz#c59341c9723f414c452975564c7c00a68d58acd2"
integrity sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==
+parse5@^6.0.0, parse5@^6.0.1:
+ version "6.0.1"
+ resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b"
+ integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==
+
parseurl@~1.3.2, parseurl@~1.3.3:
version "1.3.3"
resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
@@ -8902,6 +9499,15 @@ prompts@^2.0.1:
kleur "^3.0.3"
sisteransi "^1.0.4"
+prop-types-exact@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/prop-types-exact/-/prop-types-exact-1.2.0.tgz#825d6be46094663848237e3925a98c6e944e9869"
+ integrity sha512-K+Tk3Kd9V0odiXFP9fwDHUYRyvK3Nun3GVyPapSIs5OBkITAm15W0CPFD/YKTkMUAbc0b9CUwRQp2ybiBIq+eA==
+ dependencies:
+ has "^1.0.3"
+ object.assign "^4.1.0"
+ reflect.ownkeys "^0.2.0"
+
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"
@@ -9026,6 +9632,19 @@ raf@^3.4.1:
dependencies:
performance-now "^2.1.0"
+railroad-diagrams@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz#eb7e6267548ddedfb899c1b90e57374559cddb7e"
+ integrity sha1-635iZ1SN3t+4mcG5Dlc3RVnN234=
+
+randexp@0.4.6:
+ version "0.4.6"
+ resolved "https://registry.yarnpkg.com/randexp/-/randexp-0.4.6.tgz#e986ad5e5e31dae13ddd6f7b3019aa7c87f60ca3"
+ integrity sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ==
+ dependencies:
+ discontinuous-range "1.0.0"
+ ret "~0.1.10"
+
randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
@@ -9113,11 +9732,20 @@ react-error-overlay@^6.0.7:
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.7.tgz#1dcfb459ab671d53f660a991513cb2f0a0553108"
integrity sha512-TAv1KJFh3RhqxNvhzxj6LeT5NWklP6rDr2a0jaTfsZ5wSZWHOGeqQyejUp3xxLfPt2UpyJEcVQB/zyPcmonNFA==
-react-is@^16.12.0, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4:
+react-is@^16.12.0, react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4, react-is@^16.8.6:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
+react-query@^3.13.4:
+ version "3.13.4"
+ resolved "https://registry.yarnpkg.com/react-query/-/react-query-3.13.4.tgz#8924c4453bf8e1332bfec994390e734c41ce8dc2"
+ integrity sha512-tSjUQpZ8/Fvu2xe2WSLa3Qn7yn+199HTqnz0iPakR9J7/5uSv6JwHPO0AkH/mSpBhc7IZos842kXbGCxwLoJGg==
+ dependencies:
+ "@babel/runtime" "^7.5.5"
+ broadcast-channel "^3.4.1"
+ match-sorter "^6.0.2"
+
react-router-dom@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.2.0.tgz#9e65a4d0c45e13289e66c7b17c7e175d0ea15662"
@@ -9207,6 +9835,16 @@ react-scripts@3.4.3:
optionalDependencies:
fsevents "2.1.2"
+react-test-renderer@^16.0.0-0:
+ version "16.14.0"
+ resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.14.0.tgz#e98360087348e260c56d4fe2315e970480c228ae"
+ integrity sha512-L8yPjqPE5CZO6rKsKXRO/rVPiaCOy0tQQJbC+UjPNlobl5mad59lvPjwFsQHTvL03caVDIVr9x9/OSgDe6I5Eg==
+ dependencies:
+ object-assign "^4.1.1"
+ prop-types "^15.6.2"
+ react-is "^16.8.6"
+ scheduler "^0.19.1"
+
react@^16.13.1:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react/-/react-16.13.1.tgz#2e818822f1a9743122c063d6410d85c1e3afe48e"
@@ -9310,6 +9948,11 @@ redent@^3.0.0:
indent-string "^4.0.0"
strip-indent "^3.0.0"
+reflect.ownkeys@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/reflect.ownkeys/-/reflect.ownkeys-0.2.0.tgz#749aceec7f3fdf8b63f927a04809e90c5c0b3460"
+ integrity sha1-dJrO7H8/34tj+SegSAnpDFwLNGA=
+
regenerate-unicode-properties@^8.2.0:
version "8.2.0"
resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec"
@@ -9399,6 +10042,11 @@ relateurl@^0.2.7:
resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9"
integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=
+remove-accents@0.4.2:
+ version "0.4.2"
+ resolved "https://registry.yarnpkg.com/remove-accents/-/remove-accents-0.4.2.tgz#0a43d3aaae1e80db919e07ae254b285d9e1c7bb5"
+ integrity sha1-CkPTqq4egNuRngeuJUsoXZ4ce7U=
+
remove-trailing-separator@^1.0.1:
version "1.1.0"
resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef"
@@ -9592,6 +10240,13 @@ rimraf@2.6.3:
dependencies:
glob "^7.1.3"
+rimraf@3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a"
+ integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==
+ dependencies:
+ glob "^7.1.3"
+
rimraf@^2.5.4, rimraf@^2.6.3, rimraf@^2.7.1:
version "2.7.1"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"
@@ -9607,6 +10262,14 @@ ripemd160@^2.0.0, ripemd160@^2.0.1:
hash-base "^3.0.0"
inherits "^2.0.1"
+rst-selector-parser@^2.2.3:
+ version "2.2.3"
+ resolved "https://registry.yarnpkg.com/rst-selector-parser/-/rst-selector-parser-2.2.3.tgz#81b230ea2fcc6066c89e3472de794285d9b03d91"
+ integrity sha1-gbIw6i/MYGbInjRy3nlChdmwPZE=
+ dependencies:
+ lodash.flattendeep "^4.4.0"
+ nearley "^2.7.10"
+
rsvp@^4.8.4:
version "4.8.5"
resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734"
@@ -9673,6 +10336,11 @@ sanitize.css@^10.0.0:
resolved "https://registry.yarnpkg.com/sanitize.css/-/sanitize.css-10.0.0.tgz#b5cb2547e96d8629a60947544665243b1dc3657a"
integrity sha512-vTxrZz4dX5W86M6oVWVdOVe72ZiPs41Oi7Z6Km4W5Turyz28mrXSJhhEBZoRtzJWIv3833WKVwLSDWWkEfupMg==
+sanitize.css@^12.0.1:
+ version "12.0.1"
+ resolved "https://registry.yarnpkg.com/sanitize.css/-/sanitize.css-12.0.1.tgz#f20369357557ba2b41d7278eeb3ea691a3bee514"
+ integrity sha512-QbusSBnWHaRBZeTxsJyknwI0q+q6m1NtLBmB76JfW/rdVN7Ws6Zz70w65+430/ouVcdNVT3qwrDgrM6PaYyRtw==
+
sass-loader@8.0.2:
version "8.0.2"
resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-8.0.2.tgz#debecd8c3ce243c76454f2e8290482150380090d"
@@ -9744,7 +10412,7 @@ semver-regex@^2.0.0:
resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-2.0.0.tgz#a93c2c5844539a770233379107b38c7b4ac9d338"
integrity sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw==
-"semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0:
+"semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.0, semver@^5.7.1:
version "5.7.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
@@ -9868,6 +10536,11 @@ shallow-clone@^3.0.0:
dependencies:
kind-of "^6.0.2"
+shallowequal@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8"
+ integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==
+
shebang-command@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
@@ -10281,6 +10954,15 @@ string.prototype.matchall@^4.0.2:
regexp.prototype.flags "^1.3.0"
side-channel "^1.0.2"
+string.prototype.trim@^1.2.1:
+ version "1.2.3"
+ resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.3.tgz#d23a22fde01c1e6571a7fadcb9be11decd8061a7"
+ integrity sha512-16IL9pIBA5asNOSukPfxX2W68BaBvxyiRK16H3RA/lWW9BDosh+w7f+LhomPHpXJ82QEe7w7/rY/S1CV97raLg==
+ dependencies:
+ call-bind "^1.0.0"
+ define-properties "^1.1.3"
+ es-abstract "^1.18.0-next.1"
+
string.prototype.trimend@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913"
@@ -10289,6 +10971,14 @@ string.prototype.trimend@^1.0.1:
define-properties "^1.1.3"
es-abstract "^1.17.5"
+string.prototype.trimend@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz#a22bd53cca5c7cf44d7c9d5c732118873d6cd18b"
+ integrity sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw==
+ dependencies:
+ call-bind "^1.0.0"
+ define-properties "^1.1.3"
+
string.prototype.trimstart@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz#14af6d9f34b053f7cfc89b72f8f2ee14b9039a54"
@@ -10297,6 +10987,14 @@ string.prototype.trimstart@^1.0.1:
define-properties "^1.1.3"
es-abstract "^1.17.5"
+string.prototype.trimstart@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz#9b4cb590e123bb36564401d59824298de50fd5aa"
+ integrity sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg==
+ dependencies:
+ call-bind "^1.0.0"
+ define-properties "^1.1.3"
+
string_decoder@^1.0.0, string_decoder@^1.1.1:
version "1.3.0"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
@@ -10391,6 +11089,22 @@ style-loader@0.23.1:
loader-utils "^1.1.0"
schema-utils "^1.0.0"
+styled-components@^5, styled-components@^5.2.1:
+ version "5.2.1"
+ resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.2.1.tgz#6ed7fad2dc233825f64c719ffbdedd84ad79101a"
+ integrity sha512-sBdgLWrCFTKtmZm/9x7jkIabjFNVzCUeKfoQsM6R3saImkUnjx0QYdLwJHBjY9ifEcmjDamJDVfknWm1yxZPxQ==
+ dependencies:
+ "@babel/helper-module-imports" "^7.0.0"
+ "@babel/traverse" "^7.4.5"
+ "@emotion/is-prop-valid" "^0.8.8"
+ "@emotion/stylis" "^0.8.4"
+ "@emotion/unitless" "^0.7.4"
+ babel-plugin-styled-components ">= 1"
+ css-to-react-native "^3.0.0"
+ hoist-non-react-statics "^3.0.0"
+ shallowequal "^1.1.0"
+ supports-color "^5.5.0"
+
stylehacks@^4.0.0:
version "4.0.3"
resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-4.0.3.tgz#6718fcaf4d1e07d8a1318690881e8d96726a71d5"
@@ -10405,7 +11119,7 @@ supports-color@^2.0.0:
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=
-supports-color@^5.3.0:
+supports-color@^5.3.0, supports-color@^5.5.0:
version "5.5.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
@@ -10794,6 +11508,14 @@ universalify@^0.1.0:
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
+unload@2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/unload/-/unload-2.2.0.tgz#ccc88fdcad345faa06a92039ec0f80b488880ef7"
+ integrity sha512-B60uB5TNBLtN6/LsgAf3udH9saB5p7gqJwcFfbOEZ8BcBHnGwCf6G/TGiEqkRAxX7zAFIUtzdrXQSdL3Q/wqNA==
+ dependencies:
+ "@babel/runtime" "^7.6.2"
+ detect-node "^2.0.4"
+
unpipe@1.0.0, unpipe@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"