diff --git a/package.json b/package.json index 58e35d764..e77da573f 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ "dev:xapix": "yarn workspace @looker/extension-api-explorer develop", "dev:playground": "yarn workspace @looker/extension-playground develop", "dev:tile": "yarn workspace @looker/extension-tile-playground develop", + "dev:firestore": "yarn workspace @looker/extension-firestore develop", "clean": "rm -Rf packages/*/lib", "prepublishOnly": "jest packages/sdk-rtl packages/sdk-node/test", "fix": "yarn lint:es --fix", diff --git a/packages/extension-firestore/.gitignore b/packages/extension-firestore/.gitignore new file mode 100644 index 000000000..047009bdf --- /dev/null +++ b/packages/extension-firestore/.gitignore @@ -0,0 +1,6 @@ +node_modules +dist +.cache +.vscode +.env +.eslintcache diff --git a/packages/extension-firestore/README.md b/packages/extension-firestore/README.md new file mode 100644 index 000000000..65f773411 --- /dev/null +++ b/packages/extension-firestore/README.md @@ -0,0 +1,94 @@ +# Looker Extension Firestore Demo (React & Typescript) + +TODO - add firebase setup + +This repository demonstrate using firestore in a Looker extension using Typescript. + +It uses [React](https://reactjs.org/) and [Typescript](https://typescriptlang.org) for writing your extension, the [React Extension SDK](https://github.com/looker-open-source/sdk-codegen/tree/main/packages/extension-sdk-react) for interacting with Looker, [Looker Components](https://components.looker.com) for UI, and [Webpack](https://webpack.js.org/) for building your code. + +## Getting Started for Development + +1. Install the dependencies with [Yarn](https://yarnpkg.com/). + + ``` + yarn install + ``` + +2. Start the development server + + ``` + yarn develop + ``` + + The extension is now running and serving the JavaScript locally at https://localhost:8080/dist/bundle.js. + +3. Log in to Looker and create a new project. + + This is found under **Develop** => **Manage LookML Projects** => **New LookML Project**. + + Select "Blank Project" as your "Starting Point". This will create a new project with no files. + + 1. The extension folder has a `manifest.lkml` file. + + Either drag & upload this file into your Looker project, or create a `manifest.lkml` with the same content. Change the `id`, `label`, or `url` as needed. + + ``` + project_name: "firestore" + application: firestore { + label: "Firestore Example" + url: "https://localhost:8080/dist/bundle.js" + entitlements: { + external_api_urls : ["https://firestore.googleapis.com","https://identitytoolkit.googleapis.com","https://securetoken.googleapis.com"] + google_api_scopes: ["https://www.googleapis.com/auth/datastore","https://www.googleapis.com/auth/userinfo.email","https://www.googleapis.com/auth/firebase.database"] + scoped_user_attributes: ["firebase_config"] + } + } + ``` + +4. Create a `model` LookML file in your project. The name doesn't matter but the convention is to name it the same as the project— in this case, helloworld-js. + +- Add a connection in this model. +- [Configure the model you created](https://docs.looker.com/data-modeling/getting-started/create-projects#configuring_a_model) so that it has access to the selected connection. + We do this because Looker permissions data access via models— In order to grant / limit access to an extension, it must be associated with a model. + +5. Connect the project to Git. This can be done in multiple ways: + +- Create a new repository on GitHub or a similar service, and follow the instructions to [connect your project to Git](https://docs.looker.com/data-modeling/getting-started/setting-up-git-connection) +- A simpler but less powerful approach is to set up git with the "Bare" repository option which does not require connecting to an external Git Service. + +6. Commit the changes and deploy them to production through the Project UI. + +7. Reload the page and click the `Browse` dropdown menu. You will see the extension in the list. + +- The extension will load the JavaScript from the `url` provided in the `application` definition. By default, this is http://localhost:8080/bundle.js. If you change the port your server runs on in the package.json, you will need to also update it in the manifest.lkml. +- Refreshing the extension page will bring in any new code changes from the extension template, although some changes will hot reload. + +## Deployment + +The process above describes how to run the extension for development. Once you're done developing and ready to deploy, the production version of the extension may be deployed as follows: + +1. In the extension project directory build the extension by running `yarn build`. +2. Drag and drop the generated `dist/bundle.js` file into the Looker project interface +3. Modify the `manifest.lkml` to use `file` instead of `url`: + + ``` + project_name: "firestore" + application: firestore { + label: "Firestore Example" + file: "bundle.js + entitlements: { + external_api_urls : ["https://firestore.googleapis.com","https://identitytoolkit.googleapis.com","https://securetoken.googleapis.com"] + google_api_scopes: ["https://www.googleapis.com/auth/datastore","https://www.googleapis.com/auth/userinfo.email","https://www.googleapis.com/auth/firebase.database"] + scoped_user_attributes: ["firebase_config"] + } + } + ``` + +## Related Projects + +- [Looker Extension SDK React](https://github.com/looker-open-source/sdk-codegen/tree/main/packages/extension-sdk-react) +- [Looker Extension SDK](https://github.com/looker-open-source/sdk-codegen/tree/main/packages/extension-sdk) +- [Looker SDK](https://github.com/looker-open-source/sdk-codegen/tree/main/packages/sdk) +- [Looker Embed SDK](https://github.com/looker-open-source/embed-sdk) +- [Looker Components](https://components.looker.com/) +- [Styled components](https://www.styled-components.com/docs) diff --git a/packages/extension-firestore/manifest.lkml b/packages/extension-firestore/manifest.lkml new file mode 100644 index 000000000..44c1374ab --- /dev/null +++ b/packages/extension-firestore/manifest.lkml @@ -0,0 +1,12 @@ +project_name: "firestore" + +application: firestore { + label: "Firestore Example" + url: "https://localhost:8080/dist/bundle.js" + # file: "bundle.js + entitlements: { + external_api_urls : ["https://firestore.googleapis.com","https://identitytoolkit.googleapis.com","https://securetoken.googleapis.com"] + google_api_scopes: ["https://www.googleapis.com/auth/datastore","https://www.googleapis.com/auth/userinfo.email","https://www.googleapis.com/auth/firebase.database"] + scoped_user_attributes: ["firebase_config"] + } +} diff --git a/packages/extension-firestore/package.json b/packages/extension-firestore/package.json new file mode 100644 index 000000000..3543bd5ad --- /dev/null +++ b/packages/extension-firestore/package.json @@ -0,0 +1,44 @@ +{ + "name": "@looker/extension-firestore", + "version": "1.1.0", + "description": "Looker Extension SDK Firestore Demo", + "main": "dist/bundle.js", + "scripts": { + "analyze": "export ANALYZE_MODE=static && yarn bundle", + "bundle": "tsc && webpack --config webpack.prod.config.js", + "develop": "webpack serve --hot --disable-host-check --port 8080 --https --config webpack.dev.config.js" + }, + "author": "Looker", + "license": "MIT", + "dependencies": { + "@looker/extension-sdk": "^22.4.2", + "@looker/extension-sdk-react": "22.4.2", + "@looker/sdk": "^22.0.0", + "@looker/sdk-codegen": "^21.3.2", + "@looker/components": "^2.8.1", + "@looker/icons": "^1.5.3", + "@styled-icons/material": "^10.28.0", + "@styled-icons/material-outlined": "^10.28.0", + "@styled-icons/material-rounded": "^10.28.0", + "firebase": "^9.6.11", + "lodash": "^4.17.21", + "react": "^16.14.0", + "react-dom": "^16.14.0", + "react-is": "^16.13.1", + "react-router-dom": "^5.3.0", + "reactfire": "^4.2.1", + "semver": "^7.3.4", + "styled-components": "^5.3.1" + }, + "devDependencies": { + "@types/lodash": "^4.14.178", + "@types/redux": "^3.6.0", + "@types/styled-components": "^5.1.7", + "@looker/components-test-utils": "^1.5.5", + "@testing-library/react": "^11.2.2", + "webpack-bundle-analyzer": "^4.2.0", + "webpack-cli": "^4.6.0", + "webpack-dev-server": "^3.11.2", + "webpack-merge": "^5.7.3" + } +} diff --git a/packages/extension-firestore/src/AnimalsList.tsx b/packages/extension-firestore/src/AnimalsList.tsx new file mode 100644 index 000000000..f0c943e4d --- /dev/null +++ b/packages/extension-firestore/src/AnimalsList.tsx @@ -0,0 +1,147 @@ +/* + + MIT License + + Copyright (c) 2022 Looker Data Sciences, Inc. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + */ +import React, { useState } from 'react' +import { useFirestore, useFirestoreCollectionData } from 'reactfire' +import type { DataTableColumns } from '@looker/components' +import { + Button, + Spinner, + DataTable, + DataTableItem, + DataTableCell, + SpaceVertical, +} from '@looker/components' +import { collection, orderBy, query, addDoc } from 'firebase/firestore' + +/** + * Example based upon https://github.com/FirebaseExtended/reactfire/blob/main/example/withoutSuspense/Firestore.tsx + * + * License details: + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Firebase + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +export const AnimalsList = () => { + const firestore = useFirestore() + const animalsCollection = collection(firestore, 'animals') + const [isAscending, setIsAscending] = useState(false) + const animalsQuery = query( + animalsCollection, + orderBy('commonName', isAscending ? 'asc' : 'desc') + ) + const { status, data: animals } = useFirestoreCollectionData(animalsQuery, { + idField: 'id', + }) + + const addAnimal = () => { + const possibleAnimals = ['Dog', 'Cat', 'Iguana', 'Zebra'] + const selectedAnimal = + possibleAnimals[Math.floor(Math.random() * possibleAnimals.length)] + addDoc(animalsCollection, { commonName: selectedAnimal }) + } + + if (status === 'loading') { + return + } + + const animalColumns: DataTableColumns = [ + { + id: 'id', + title: 'ID', + type: 'string', + }, + { + id: 'name', + title: 'Name', + type: 'string', + }, + ] + + const animalCountColumns: DataTableColumns = [ + { + id: 'name', + title: 'Name', + type: 'string', + }, + { + id: 'count', + title: 'Count', + type: 'number', + }, + ] + + return ( + + + + {animals.map(({ id, commonName }) => ( + + {id} + {commonName} + + ))} + + + {Array.from( + animals.reduce((animalCountMap, animal) => { + const currentCount = animalCountMap.get(animal.commonName) ?? 0 + return animalCountMap.set(animal.commonName, currentCount + 1) + }, new Map()) + ).map((animalStat: [string, number]) => { + const [animalName, animalCount] = animalStat + return ( + + {animalName} + {animalCount} + + ) + })} + + + + ) +} diff --git a/packages/extension-firestore/src/App.tsx b/packages/extension-firestore/src/App.tsx new file mode 100644 index 000000000..b8015a80e --- /dev/null +++ b/packages/extension-firestore/src/App.tsx @@ -0,0 +1,37 @@ +/* + + MIT License + + Copyright (c) 2022 Looker Data Sciences, Inc. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + */ +import React from 'react' +import { ComponentsProvider } from '@looker/components' +import { ExtensionProvider40 } from '@looker/extension-sdk-react' +import { AppConfigurator } from './AppConfigurator' + +export const App = () => ( + + + + + +) diff --git a/packages/extension-firestore/src/AppConfigurator.tsx b/packages/extension-firestore/src/AppConfigurator.tsx new file mode 100644 index 000000000..9e7214fd5 --- /dev/null +++ b/packages/extension-firestore/src/AppConfigurator.tsx @@ -0,0 +1,75 @@ +/* + + MIT License + + Copyright (c) 2022 Looker Data Sciences, Inc. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + */ +import React, { useContext, useState, useEffect } from 'react' +import { MessageBar } from '@looker/components' +import { ExtensionContext40 } from '@looker/extension-sdk-react' +import { FirebaseAppProvider } from 'reactfire' +import { Firestore } from './Firestore' + +export const AppConfigurator = () => { + const [firebaseConfig, setFirebaseConfig] = useState() + const [firebaseConfigValid, setFirebaseConfigValid] = useState< + boolean | undefined + >() + const { extensionSDK } = useContext(ExtensionContext40) + + useEffect(() => { + const configure = async () => { + try { + const config = + (await extensionSDK.userAttributeGetItem('firebase_config')) || '' + setFirebaseConfig(JSON.parse(config)) + setFirebaseConfigValid(true) + } catch (error) { + setFirebaseConfigValid(false) + console.error(error) + } + } + if (firebaseConfigValid === undefined) { + configure() + } + }, [ + extensionSDK, + firebaseConfigValid, + setFirebaseConfig, + setFirebaseConfigValid, + ]) + + return ( + <> + {firebaseConfigValid === false && ( + + Invalid firebase configuration + + )} + {firebaseConfigValid && ( + + + + )} + + ) +} diff --git a/packages/extension-firestore/src/Counter.tsx b/packages/extension-firestore/src/Counter.tsx new file mode 100644 index 000000000..686f0bcfc --- /dev/null +++ b/packages/extension-firestore/src/Counter.tsx @@ -0,0 +1,70 @@ +/* + + MIT License + + Copyright (c) 2022 Looker Data Sciences, Inc. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + */ +import React from 'react' +import { useFirestore, useFirestoreDocData } from 'reactfire' +import { Button, Text, Space, Spinner } from '@looker/components' +import { doc, increment, updateDoc } from 'firebase/firestore' + +/** + * Example based upon https://github.com/FirebaseExtended/reactfire/blob/main/example/withoutSuspense/Firestore.tsx + * + * License details: + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Firebase + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +export const Counter = () => { + const firestore = useFirestore() + const ref = doc(firestore, 'count', 'counter') + const { status, data: count } = useFirestoreDocData(ref) + + const incrementCounter = (amountToIncrement: number) => { + updateDoc(ref, { + value: increment(amountToIncrement), + }) + } + + if (status === 'loading') { + return + } + + return ( + + + {count.value} + + + ) +} diff --git a/packages/extension-firestore/src/Firestore.spec.tsx b/packages/extension-firestore/src/Firestore.spec.tsx new file mode 100644 index 000000000..3af8fc190 --- /dev/null +++ b/packages/extension-firestore/src/Firestore.spec.tsx @@ -0,0 +1,40 @@ +/* + + MIT License + + Copyright (c) 2022 Looker Data Sciences, Inc. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + */ +import React from 'react' +import { screen } from '@testing-library/react' +import { renderWithExtensionContext } from './__mocks__/render_with_extension' +import { Firestore } from './Firestore' + +describe('Firestore', () => { + test('it renders', async () => { + const ok = (result: { display_name: string }) => result + const me = () => ({ + display_name: "Rosie O'Grady", + }) + renderWithExtensionContext(, {}, { core40SDK: { me, ok } }) + await screen.findByText("Hello, Rosie O'Grady") + }) +}) diff --git a/packages/extension-firestore/src/Firestore.tsx b/packages/extension-firestore/src/Firestore.tsx new file mode 100644 index 000000000..ab5e72248 --- /dev/null +++ b/packages/extension-firestore/src/Firestore.tsx @@ -0,0 +1,107 @@ +/* + + MIT License + + Copyright (c) 2022 Looker Data Sciences, Inc. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + */ +import React, { useCallback, useContext, useEffect, useState } from 'react' +import { getFirestore } from 'firebase/firestore' +import { + getAuth, + signInWithCredential, + GoogleAuthProvider, +} from 'firebase/auth' +import { FirestoreProvider, useFirebaseApp } from 'reactfire' +import { + SpaceVertical, + MessageBar, + Button, + Tabs2, + Tab2, +} from '@looker/components' +import { ExtensionContext40 } from '@looker/extension-sdk-react' +import { Counter } from './Counter' +import { AnimalsList } from './AnimalsList' + +export const Firestore = () => { + const [authorized, setAuthorized] = useState() + const firebaseApp = useFirebaseApp() + const firebaseAuth = getAuth(firebaseApp) + const firestoreInstance = getFirestore(firebaseApp) + const { extensionSDK } = useContext(ExtensionContext40) + const [errorMessage, setErrorMessage] = useState() + + const authorize = useCallback(async () => { + setErrorMessage(undefined) + try { + const googleAccessToken = await extensionSDK.getGoogleAccessToken() + if (googleAccessToken) { + const { access_token } = googleAccessToken + const credential = GoogleAuthProvider.credential(null, access_token) + await signInWithCredential(firebaseAuth, credential) + setAuthorized(true) + } else { + setAuthorized(false) + setErrorMessage('Google credentials are missing') + } + } catch (error: any) { + setAuthorized(false) + console.error(JSON.stringify(error, null, 2)) + setErrorMessage('An error occurred authorizing access to firestore!') + } + }, [extensionSDK, setAuthorized, setErrorMessage]) + + useEffect(() => { + if (!authorized) { + authorize() + } + }, [authorized, setAuthorized]) + + const reauthorize = useCallback(async () => { + await firebaseAuth.signOut() + await extensionSDK.reauthorizeGoogleApiScopes() + await authorize() + }, [authorize, extensionSDK]) + + return ( + + + {errorMessage && ( + {errorMessage} + )} + {authorized === false && ( + + )} + {authorized && ( + + + + + + + + + )} + + + ) +} diff --git a/packages/extension-firestore/src/__mocks__/render_with_extension.tsx b/packages/extension-firestore/src/__mocks__/render_with_extension.tsx new file mode 100644 index 000000000..2439bff59 --- /dev/null +++ b/packages/extension-firestore/src/__mocks__/render_with_extension.tsx @@ -0,0 +1,121 @@ +/* + + MIT License + + Copyright (c) 2022 Looker Data Sciences, Inc. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + */ + +import type { ReactNode } from 'react' +import React from 'react' +import { renderWithTheme } from '@looker/components-test-utils' +import type { RenderResult } from '@testing-library/react' +import type { + ExtensionContextData2, + ExtensionContextData, +} from '@looker/extension-sdk-react' +import { + ExtensionContext2, + ExtensionContext, +} from '@looker/extension-sdk-react' +import type { ExtensionHostApi, ExtensionSDK } from '@looker/extension-sdk' +import { registerHostApi } from '@looker/extension-sdk' +import { MemoryRouter } from 'react-router-dom' + +const getExtensionSDK = (extensionSDKOverride: Partial) => { + const extensionSDK = { + lookerHostData: {}, + error: () => { + // noop + }, + ...extensionSDKOverride, + } as ExtensionHostApi + registerHostApi(extensionSDK) + return extensionSDK +} + +const getExtensionContext2 = ( + extensionSDKOverride: Partial, + contextOverride: Partial> +): ExtensionContextData2 => + ({ + extensionSDK: getExtensionSDK(extensionSDKOverride), + coreSDK: {}, + route: '', + ...contextOverride, + } as ExtensionContextData2) + +const withExtensionContext2 = ( + component: ReactNode, + extensionSDKOverride: Partial, + contextOverride: Partial> +) => ( + + + {component} + + +) + +export const renderWithExtensionContext2 = ( + component: ReactNode, + extensionSDKOverride = {}, + contextOverride = {} +): RenderResult => + renderWithTheme( + withExtensionContext2(component, extensionSDKOverride, contextOverride) + ) + +const getExtensionContext = ( + extensionSDKOverride: Partial, + contextOverride: Partial +): ExtensionContextData => + ({ + extensionSDK: getExtensionSDK(extensionSDKOverride), + coreSDK: {}, + route: '', + ...contextOverride, + } as ExtensionContextData) + +const withExtensionContext = ( + component: ReactNode, + extensionSDKOverride: Partial, + contextOverride: Partial +) => ( + + + {component} + + +) + +export const renderWithExtensionContext = ( + component: ReactNode, + extensionSDKOverride = {}, + contextOverride = {} +): RenderResult => + renderWithTheme( + withExtensionContext(component, extensionSDKOverride, contextOverride) + ) diff --git a/packages/extension-firestore/src/index.tsx b/packages/extension-firestore/src/index.tsx new file mode 100644 index 000000000..4488f6502 --- /dev/null +++ b/packages/extension-firestore/src/index.tsx @@ -0,0 +1,34 @@ +/* + + MIT License + + Copyright (c) 2022 Looker Data Sciences, Inc. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + */ +import React from 'react' +import ReactDOM from 'react-dom' +import { App } from './App' + +window.addEventListener('DOMContentLoaded', (_) => { + const root = document.createElement('div') + document.body.appendChild(root) + ReactDOM.render(, root) +}) diff --git a/packages/extension-firestore/tsconfig.build.json b/packages/extension-firestore/tsconfig.build.json new file mode 100644 index 000000000..51db2ccb4 --- /dev/null +++ b/packages/extension-firestore/tsconfig.build.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.build.json", + "compilerOptions": { + "rootDir": "./src", + "outDir": "./lib" + }, + "include": ["src/**/*"] +} diff --git a/packages/extension-firestore/webpack.dev.config.js b/packages/extension-firestore/webpack.dev.config.js new file mode 100644 index 000000000..412111812 --- /dev/null +++ b/packages/extension-firestore/webpack.dev.config.js @@ -0,0 +1,45 @@ +/* + + MIT License + + Copyright (c) 2022 Looker Data Sciences, Inc. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + */ + +const { merge } = require('webpack-merge') +const base = require('../../webpack.base.config')(__dirname) +const browser = require('../../webpack.browser.config')() + +module.exports = merge(base, browser, { + mode: 'development', + devServer: { + historyApiFallback: { + disableDotRule: true, + }, + publicPath: '/dist/', + headers: { + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS', + 'Access-Control-Allow-Headers': + 'X-Requested-With, content-type, Authorization', + }, + }, +}) diff --git a/packages/extension-firestore/webpack.prod.config.js b/packages/extension-firestore/webpack.prod.config.js new file mode 100644 index 000000000..48d3b9cb8 --- /dev/null +++ b/packages/extension-firestore/webpack.prod.config.js @@ -0,0 +1,35 @@ +/* + + MIT License + + Copyright (c) 2022 Looker Data Sciences, Inc. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + */ +const { merge } = require('webpack-merge') +const base = require('../../webpack.base.config')(__dirname) +const browser = require('../../webpack.browser.config')() + +module.exports = merge(base, browser, { + mode: 'production', + optimization: { + chunkIds: 'named', + }, +}) diff --git a/packages/extension-sdk/src/connect/extension_host_api.ts b/packages/extension-sdk/src/connect/extension_host_api.ts index 0de673f98..ed868e364 100644 --- a/packages/extension-sdk/src/connect/extension_host_api.ts +++ b/packages/extension-sdk/src/connect/extension_host_api.ts @@ -44,6 +44,7 @@ import type { FetchResponseBodyType, LookerHostData, ApiVersion, + GoogleAccessToken, } from './types' import { ExtensionEvent, @@ -431,6 +432,21 @@ export class ExtensionHostApiImpl implements ExtensionHostApi { this.send(ExtensionRequestType.EXTENSION_UNLOADED, {}) } + async getGoogleAccessToken( + forceTokenRefresh?: boolean + ): Promise { + return this.sendAndReceive(ExtensionRequestType.GET_GOOGLE_ACCESS_TOKEN, { + payload: forceTokenRefresh, + }) + } + + async reauthorizeGoogleApiScopes(): Promise { + return this.sendAndReceive( + ExtensionRequestType.REAUTHORIZE_GOOGLE_API_SCOPES, + {} + ) + } + createFetchProxy( baseUrl?: string, init?: FetchCustomParameters, diff --git a/packages/extension-sdk/src/connect/types.ts b/packages/extension-sdk/src/connect/types.ts index 9206b73bc..e290d9abe 100644 --- a/packages/extension-sdk/src/connect/types.ts +++ b/packages/extension-sdk/src/connect/types.ts @@ -163,6 +163,18 @@ export enum ExtensionRequestType { * Open schedule dialog. */ TILE_OPEN_SCHEDULE_DIALOG = 'TILE_OPEN_SCHEDULE_DIALOG', + /** + * Get the google access token. Will automatically refresh the + * token if needed. + */ + GET_GOOGLE_ACCESS_TOKEN = 'GET_GOOGLE_ACCESS_TOKEN', + /** + * Google API scopes should be authorized before the extension + * is loaded. It is possible that the scope authorizations + * can be revoked after the extension is loaded. This mechanism + * allows the extension to request re-authorization. + */ + REAUTHORIZE_GOOGLE_API_SCOPES = 'REAUTHORIZE_GOOGLE_API_SCOPES', } /** @@ -576,6 +588,10 @@ export interface FetchProxy { responseBodyType?: FetchResponseBodyType ): Promise } +export interface GoogleAccessToken { + access_token: string + expires_at: number +} /** * Public extension SDK @@ -872,4 +888,23 @@ export interface ExtensionSDK { * 2. The Looker host system supports it. */ isDashboardMountSupported: boolean + + /** + * Get the google access token. If the token has expired + * set forceTokenRefresh to refresh it. The host will do + * this for you if it determines that the token is about + * to expire. + */ + getGoogleAccessToken: ( + forceTokenRefresh?: boolean + ) => Promise + + /** + * Reauthorize the google api scopes associated with the extension. + * In general it is unlikely that it will be necessary to call this. + * The scenario where this is necessary is when the application + * the extension is associated with has its third party access + * removed. + */ + reauthorizeGoogleApiScopes: () => Promise } diff --git a/yarn.lock b/yarn.lock index 2da3131b1..9f6664513 100644 --- a/yarn.lock +++ b/yarn.lock @@ -96,6 +96,13 @@ dependencies: "@babel/types" "^7.12.13" +"@babel/helper-annotate-as-pure@^7.16.0": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz#bb2339a7534a9c128e3102024c60760a3a7f3862" + integrity sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw== + dependencies: + "@babel/types" "^7.16.7" + "@babel/helper-builder-binary-assignment-operator-visitor@^7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.12.13.tgz#6bc20361c88b0a74d05137a65cac8d3cbf6f61fc" @@ -193,6 +200,13 @@ dependencies: "@babel/types" "^7.15.4" +"@babel/helper-module-imports@^7.16.0": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437" + integrity sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg== + dependencies: + "@babel/types" "^7.16.7" + "@babel/helper-module-transforms@^7.12.1", "@babel/helper-module-transforms@^7.13.0", "@babel/helper-module-transforms@^7.14.0": version "7.14.0" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.14.0.tgz#8fcf78be220156f22633ee204ea81f73f826a8ad" @@ -269,6 +283,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz#220df993bfe904a4a6b02ab4f3385a5ebf6e2389" integrity sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w== +"@babel/helper-validator-identifier@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" + integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== + "@babel/helper-validator-option@^7.12.17": version "7.12.17" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz#d1fbf012e1a79b7eebbfdc6d270baaf8d9eb9831" @@ -1001,6 +1020,13 @@ dependencies: regenerator-runtime "^0.13.4" +"@babel/runtime@^7.12.13": + version "7.18.3" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.18.3.tgz#c7b654b57f6f63cf7f8b418ac9ca04408c4579f4" + integrity sha512-38Y8f7YUhce/K7RMwTp7m0uCumpv9hZkitCbBClqQIow1qSbCvGkcegKOXpEWCQLfWmevgRiWokZ1GkpfhbZug== + dependencies: + regenerator-runtime "^0.13.4" + "@babel/template@^7.12.13", "@babel/template@^7.12.7", "@babel/template@^7.3.3": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.13.tgz#530265be8a2589dbb37523844c5bcb55947fb327" @@ -1032,6 +1058,14 @@ "@babel/helper-validator-identifier" "^7.14.9" to-fast-properties "^2.0.0" +"@babel/types@^7.16.7": + version "7.18.4" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.18.4.tgz#27eae9b9fd18e9dccc3f9d6ad051336f307be354" + integrity sha512-ThN1mBcMq5pG/Vm2IcBmPPfyPXbd8S02rS+OBIDENdufvqC7Z/jHPCv9IcP01277aKtDI8g/2XysBN4hA8niiw== + dependencies: + "@babel/helper-validator-identifier" "^7.16.7" + to-fast-properties "^2.0.0" + "@bcoe/v8-coverage@^0.2.3": version "0.2.3" resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" @@ -1084,11 +1118,23 @@ dependencies: "@emotion/memoize" "0.7.4" +"@emotion/is-prop-valid@^1.1.0": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.1.2.tgz#34ad6e98e871aa6f7a20469b602911b8b11b3a95" + integrity sha512-3QnhqeL+WW88YjYbQL5gUIkthuMw7a0NGbZ7wfFVk2kg/CK5w8w5FFa0RzWjyY1+sujN0NWbtSHH6OJmWHtJpQ== + dependencies: + "@emotion/memoize" "^0.7.4" + "@emotion/memoize@0.7.4", "@emotion/memoize@^0.7.1": version "0.7.4" resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb" integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw== +"@emotion/memoize@^0.7.4": + version "0.7.5" + resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.5.tgz#2c40f81449a4e554e9fc6396910ed4843ec2be50" + integrity sha512-igX9a37DR2ZPGYtV6suZ6whr8pTFtyHL3K/oLUotxpSVO2ASaprmAe2Dkq7tBo7CRY7MMDrAa9nuQP9/YG8FxQ== + "@emotion/serialize@^0.11.15", "@emotion/serialize@^0.11.16": version "0.11.16" resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-0.11.16.tgz#dee05f9e96ad2fb25a5206b6d759b2d1ed3379ad" @@ -1219,6 +1265,392 @@ resolved "https://registry.yarnpkg.com/@exodus/schemasafe/-/schemasafe-1.0.0-rc.3.tgz#dda2fbf3dafa5ad8c63dadff7e01d3fdf4736025" integrity sha512-GoXw0U2Qaa33m3eUcxuHnHpNvHjNlLo0gtV091XBpaRINaB4X6FGCG5XKxSFNFiPpugUDqNruHzaqpTdDm4AOg== +"@firebase/analytics-compat@0.1.10": + version "0.1.10" + resolved "https://registry.yarnpkg.com/@firebase/analytics-compat/-/analytics-compat-0.1.10.tgz#1e14677cdccad5052c6ccec49d2a92aab40be2a1" + integrity sha512-7zfB+BBO5RbF7RSHOA4ZPyLvOEEvMOhRbfIjh5ZmizAQY2J6tZB8t+dwQ/q4hqZVGgw4ds4g0JYuRKZKYsWADg== + dependencies: + "@firebase/analytics" "0.7.9" + "@firebase/analytics-types" "0.7.0" + "@firebase/component" "0.5.14" + "@firebase/util" "1.6.0" + tslib "^2.1.0" + +"@firebase/analytics-types@0.7.0": + version "0.7.0" + resolved "https://registry.yarnpkg.com/@firebase/analytics-types/-/analytics-types-0.7.0.tgz#91960e7c87ce8bf18cf8dd9e55ccbf5dc3989b5d" + integrity sha512-DNE2Waiwy5+zZnCfintkDtBfaW6MjIG883474v6Z0K1XZIvl76cLND4iv0YUb48leyF+PJK1KO2XrgHb/KpmhQ== + +"@firebase/analytics@0.7.9": + version "0.7.9" + resolved "https://registry.yarnpkg.com/@firebase/analytics/-/analytics-0.7.9.tgz#07f43100a1ab5750c7d8207f31aeba0a42bcf562" + integrity sha512-h/2L2q4/+mmV9EdvVC3XwFFbKSh8bvaYu4DMJIKnPAuGze6W5ALBLkK2GcVti6Kz1NTMJ3puxTRWE9XxRGZipQ== + dependencies: + "@firebase/component" "0.5.14" + "@firebase/installations" "0.5.9" + "@firebase/logger" "0.3.2" + "@firebase/util" "1.6.0" + tslib "^2.1.0" + +"@firebase/app-check-compat@0.2.8": + version "0.2.8" + resolved "https://registry.yarnpkg.com/@firebase/app-check-compat/-/app-check-compat-0.2.8.tgz#eb5027a2ffa88f78a62639d3c7dd253ecb9ee49f" + integrity sha512-EAqFa0juE2xc52IGh2nv8E+avTLsZfbO7fkJnhPu07e5FU39pptcsRckTdHU7v1/DuWuigUVFcOD5iic9I8TQw== + dependencies: + "@firebase/app-check" "0.5.8" + "@firebase/app-check-types" "0.4.0" + "@firebase/component" "0.5.14" + "@firebase/logger" "0.3.2" + "@firebase/util" "1.6.0" + tslib "^2.1.0" + +"@firebase/app-check-interop-types@0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@firebase/app-check-interop-types/-/app-check-interop-types-0.1.0.tgz#83afd9d41f99166c2bdb2d824e5032e9edd8fe53" + integrity sha512-uZfn9s4uuRsaX5Lwx+gFP3B6YsyOKUE+Rqa6z9ojT4VSRAsZFko9FRn6OxQUA1z5t5d08fY4pf+/+Dkd5wbdbA== + +"@firebase/app-check-types@0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@firebase/app-check-types/-/app-check-types-0.4.0.tgz#7007a9d1d720db20bcf466fe6785c96feaa0a82d" + integrity sha512-SsWafqMABIOu7zLgWbmwvHGOeQQVQlwm42kwwubsmfLmL4Sf5uGpBfDhQ0CAkpi7bkJ/NwNFKafNDL9prRNP0Q== + +"@firebase/app-check@0.5.8": + version "0.5.8" + resolved "https://registry.yarnpkg.com/@firebase/app-check/-/app-check-0.5.8.tgz#80fcdadd59b95669cf216c345281dd29cdc1eb57" + integrity sha512-DgrXnrJT0S5csa5CsvmWWSWqy61T3rOE2iZ/L4Q8+xZsjU2McpUj8g/lU8NDa4qc5mGRZ/Qjozqog1H3pwPgGw== + dependencies: + "@firebase/component" "0.5.14" + "@firebase/logger" "0.3.2" + "@firebase/util" "1.6.0" + tslib "^2.1.0" + +"@firebase/app-compat@0.1.26": + version "0.1.26" + resolved "https://registry.yarnpkg.com/@firebase/app-compat/-/app-compat-0.1.26.tgz#46ca3ea0929a28b6d894f6d4fd8d49a0fe2b66ca" + integrity sha512-i5UTq1HZAHuhe7RNjgFSezbow4jVxc2oe3Gndsv+Hdut92f8L0AyssOtdU2iOylLlxbTijewAXXui4FAUzXubw== + dependencies: + "@firebase/app" "0.7.25" + "@firebase/component" "0.5.14" + "@firebase/logger" "0.3.2" + "@firebase/util" "1.6.0" + tslib "^2.1.0" + +"@firebase/app-types@0.7.0": + version "0.7.0" + resolved "https://registry.yarnpkg.com/@firebase/app-types/-/app-types-0.7.0.tgz#c9e16d1b8bed1a991840b8d2a725fb58d0b5899f" + integrity sha512-6fbHQwDv2jp/v6bXhBw2eSRbNBpxHcd1NBF864UksSMVIqIyri9qpJB1Mn6sGZE+bnDsSQBC5j2TbMxYsJQkQg== + +"@firebase/app@0.7.25": + version "0.7.25" + resolved "https://registry.yarnpkg.com/@firebase/app/-/app-0.7.25.tgz#a5ee629d7f957579d5b25105c70316886a75cfc3" + integrity sha512-OemDA3NZS1oEbAPFlWHeVI8Od26ZHAXUivUWFYIsYrw+YjS7FloltwyHB06Q8LQyPJIBPubGkEuzNTHz32EDCQ== + dependencies: + "@firebase/component" "0.5.14" + "@firebase/logger" "0.3.2" + "@firebase/util" "1.6.0" + idb "7.0.1" + tslib "^2.1.0" + +"@firebase/auth-compat@0.2.15": + version "0.2.15" + resolved "https://registry.yarnpkg.com/@firebase/auth-compat/-/auth-compat-0.2.15.tgz#dbd04173657fdf525d9da89433b64cd3c658a1c4" + integrity sha512-Kl8pujKWVBJ+76h4tRsS5xI9Dvk8MVSP6eN82rnEgmCxiUsnVj5Adb/WzvS3p4/l++4mRSAEnlIVxZ2Pyaeirg== + dependencies: + "@firebase/auth" "0.20.2" + "@firebase/auth-types" "0.11.0" + "@firebase/component" "0.5.14" + "@firebase/util" "1.6.0" + node-fetch "2.6.7" + selenium-webdriver "4.1.2" + tslib "^2.1.0" + +"@firebase/auth-interop-types@0.1.6": + version "0.1.6" + resolved "https://registry.yarnpkg.com/@firebase/auth-interop-types/-/auth-interop-types-0.1.6.tgz#5ce13fc1c527ad36f1bb1322c4492680a6cf4964" + integrity sha512-etIi92fW3CctsmR9e3sYM3Uqnoq861M0Id9mdOPF6PWIg38BXL5k4upCNBggGUpLIS0H1grMOvy/wn1xymwe2g== + +"@firebase/auth-types@0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@firebase/auth-types/-/auth-types-0.11.0.tgz#b9c73c60ca07945b3bbd7a097633e5f78fa9e886" + integrity sha512-q7Bt6cx+ySj9elQHTsKulwk3+qDezhzRBFC9zlQ1BjgMueUOnGMcvqmU0zuKlQ4RhLSH7MNAdBV2znVaoN3Vxw== + +"@firebase/auth@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@firebase/auth/-/auth-0.20.2.tgz#fbd080a1ae279f81615cf03960fd6b9769f615c6" + integrity sha512-anv2dhHXnlHSuXDuXIoCm/w/JJ+SiQ1TAKgNVYlhfq+yvx9Op8CxfTqcfBwfbIZ1gizw4PNLuk82m8KelsKl6Q== + dependencies: + "@firebase/component" "0.5.14" + "@firebase/logger" "0.3.2" + "@firebase/util" "1.6.0" + node-fetch "2.6.7" + selenium-webdriver "4.1.2" + tslib "^2.1.0" + +"@firebase/component@0.5.14": + version "0.5.14" + resolved "https://registry.yarnpkg.com/@firebase/component/-/component-0.5.14.tgz#23d2cc9f4aff5a516c91553a433326d366166bc3" + integrity sha512-ct2p1MTMV5P/nGIlkC3XjAVwHwjsIZaeo8JVyDAkJCNTROu5mYX3FBK16hjIUIIVJDpgnnzFh9nP74gciL4WrA== + dependencies: + "@firebase/util" "1.6.0" + tslib "^2.1.0" + +"@firebase/database-compat@0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@firebase/database-compat/-/database-compat-0.2.0.tgz#3471cde00a6fe442a5c6106a23c20336f02221d7" + integrity sha512-t2HVI1RrMz8cbmhyo2LQGSInhRN9DZTDKXm55iFQgSihcnCbfoMAFyRv/FFa1Y+iERgcDI8LaOMS/LTjpYVz4g== + dependencies: + "@firebase/component" "0.5.14" + "@firebase/database" "0.13.0" + "@firebase/database-types" "0.9.8" + "@firebase/logger" "0.3.2" + "@firebase/util" "1.6.0" + tslib "^2.1.0" + +"@firebase/database-types@0.9.8": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@firebase/database-types/-/database-types-0.9.8.tgz#5a9bb1d2c492ad635eff5f3cfbe6a0ea6a2463e7" + integrity sha512-bI7bwF5xc0nPi6Oa3JVt6JJdfhVAnEpCwgfTNILR4lYDPtxdxlRXhZzQ5lfqlCj7PR+drKh9RvMu6C24N1q04w== + dependencies: + "@firebase/app-types" "0.7.0" + "@firebase/util" "1.6.0" + +"@firebase/database@0.13.0": + version "0.13.0" + resolved "https://registry.yarnpkg.com/@firebase/database/-/database-0.13.0.tgz#48018ab8f5a3ad12ec7c245d83b8b5749eb37189" + integrity sha512-lskyf5+FDnytrPJt3MLjkTDxYxutKtaYL7j/Z/De2DSVZJSR+weE/D/r47iK/+tyzMaew2v3joSgZOHvVlWshw== + dependencies: + "@firebase/auth-interop-types" "0.1.6" + "@firebase/component" "0.5.14" + "@firebase/logger" "0.3.2" + "@firebase/util" "1.6.0" + faye-websocket "0.11.4" + tslib "^2.1.0" + +"@firebase/firestore-compat@0.1.18": + version "0.1.18" + resolved "https://registry.yarnpkg.com/@firebase/firestore-compat/-/firestore-compat-0.1.18.tgz#50f19ceea1b95a5017557db9b9154627ffc12821" + integrity sha512-D6VXudL/B2jlZ6MGpsDPHHm/DSpfKuUOnEb5wwH89Sw0nW5snSMNG8QfYTQYKUxrX35ma+nWUnaa18LlVTUMXQ== + dependencies: + "@firebase/component" "0.5.14" + "@firebase/firestore" "3.4.9" + "@firebase/firestore-types" "2.5.0" + "@firebase/util" "1.6.0" + tslib "^2.1.0" + +"@firebase/firestore-types@2.5.0": + version "2.5.0" + resolved "https://registry.yarnpkg.com/@firebase/firestore-types/-/firestore-types-2.5.0.tgz#16fca40b6980fdb000de86042d7a96635f2bcdd7" + integrity sha512-I6c2m1zUhZ5SH0cWPmINabDyH5w0PPFHk2UHsjBpKdZllzJZ2TwTkXbDtpHUZNmnc/zAa0WNMNMvcvbb/xJLKA== + +"@firebase/firestore@3.4.9": + version "3.4.9" + resolved "https://registry.yarnpkg.com/@firebase/firestore/-/firestore-3.4.9.tgz#2f7ea62572ec027d9f187fb03f1e2567cb5f29ae" + integrity sha512-EiSG/uYDyUmrrHlwrsP9WqWI8ChD0hUW/+0MS3NDh8Cfo1Dfb/sM3YWKzgnIZ3wKTxn/nbe9oidHZp5cqI9G+w== + dependencies: + "@firebase/component" "0.5.14" + "@firebase/logger" "0.3.2" + "@firebase/util" "1.6.0" + "@firebase/webchannel-wrapper" "0.6.1" + "@grpc/grpc-js" "^1.3.2" + "@grpc/proto-loader" "^0.6.0" + node-fetch "2.6.7" + tslib "^2.1.0" + +"@firebase/functions-compat@0.2.1": + version "0.2.1" + resolved "https://registry.yarnpkg.com/@firebase/functions-compat/-/functions-compat-0.2.1.tgz#249c4750fdb0cc4cc29bb6e8d45f6a19b403a671" + integrity sha512-1epI+TGb3CxpQrnoSJnKMUqBLn9b6KA1Rro6ISmZIEkaDEi8p8q3UI917XP+OewiPG71xvpySiEIIxWyktcl+A== + dependencies: + "@firebase/component" "0.5.14" + "@firebase/functions" "0.8.1" + "@firebase/functions-types" "0.5.0" + "@firebase/util" "1.6.0" + tslib "^2.1.0" + +"@firebase/functions-types@0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@firebase/functions-types/-/functions-types-0.5.0.tgz#b50ba95ccce9e96f7cda453228ffe1684645625b" + integrity sha512-qza0M5EwX+Ocrl1cYI14zoipUX4gI/Shwqv0C1nB864INAD42Dgv4v94BCyxGHBg2kzlWy8PNafdP7zPO8aJQA== + +"@firebase/functions@0.8.1": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@firebase/functions/-/functions-0.8.1.tgz#690ff9582442d2deeeb5e1ccad50047c0dcec77f" + integrity sha512-UF5187TPn1Q1sFmAUU1oZdKub1t0Z6MAjcskGS6CV4OwAkILZQ9v38LIbo3wnA62R5hr3IFpdEJxKkqHojMwSg== + dependencies: + "@firebase/app-check-interop-types" "0.1.0" + "@firebase/auth-interop-types" "0.1.6" + "@firebase/component" "0.5.14" + "@firebase/messaging-interop-types" "0.1.0" + "@firebase/util" "1.6.0" + node-fetch "2.6.7" + tslib "^2.1.0" + +"@firebase/installations@0.5.9": + version "0.5.9" + resolved "https://registry.yarnpkg.com/@firebase/installations/-/installations-0.5.9.tgz#43acb123ee19010e1ec3355e0ab86e1fb2b2687a" + integrity sha512-0XvF9ig8Zj7MWP4Aq5/Wcyjq9f/cDtD6DKFJhp3BT1AjmACdmq7WD72xok8UBhkOiqymIiGd5eQf7rX225D2Sw== + dependencies: + "@firebase/component" "0.5.14" + "@firebase/util" "1.6.0" + idb "7.0.1" + tslib "^2.1.0" + +"@firebase/logger@0.3.2": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@firebase/logger/-/logger-0.3.2.tgz#5046ffa8295c577846d54b6ca95645a03809800e" + integrity sha512-lzLrcJp9QBWpo40OcOM9B8QEtBw2Fk1zOZQdvv+rWS6gKmhQBCEMc4SMABQfWdjsylBcDfniD1Q+fUX1dcBTXA== + dependencies: + tslib "^2.1.0" + +"@firebase/messaging-compat@0.1.13": + version "0.1.13" + resolved "https://registry.yarnpkg.com/@firebase/messaging-compat/-/messaging-compat-0.1.13.tgz#2a4b4083228e118a44c29ea13ded4e68870bf8aa" + integrity sha512-kGuzjpl+pcTRmEgGDjyOKQnxxQgC7wIJIIHhLMIpfxHHL5+ysN1Tjq0Ztr1t/gcdHKErtnD/n9To5eoGZHqpzA== + dependencies: + "@firebase/component" "0.5.14" + "@firebase/messaging" "0.9.13" + "@firebase/util" "1.6.0" + tslib "^2.1.0" + +"@firebase/messaging-interop-types@0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@firebase/messaging-interop-types/-/messaging-interop-types-0.1.0.tgz#bdac02dd31edd5cb9eec37b1db698ea5e2c1a631" + integrity sha512-DbvUl/rXAZpQeKBnwz0NYY5OCqr2nFA0Bj28Fmr3NXGqR4PAkfTOHuQlVtLO1Nudo3q0HxAYLa68ZDAcuv2uKQ== + +"@firebase/messaging@0.9.13": + version "0.9.13" + resolved "https://registry.yarnpkg.com/@firebase/messaging/-/messaging-0.9.13.tgz#443499868484cbeb8cbbfb2f8e0ca208f09ca336" + integrity sha512-wR/SGYGG/bmz1gRqm6/eGI6zRg/X3qNP0BCk0Oa6xVDKK04UCE9zNRgQYgCSKNP+zuLfDhpHbXvvXQp9/vBYVA== + dependencies: + "@firebase/component" "0.5.14" + "@firebase/installations" "0.5.9" + "@firebase/messaging-interop-types" "0.1.0" + "@firebase/util" "1.6.0" + idb "7.0.1" + tslib "^2.1.0" + +"@firebase/performance-compat@0.1.9": + version "0.1.9" + resolved "https://registry.yarnpkg.com/@firebase/performance-compat/-/performance-compat-0.1.9.tgz#db4cfea17f39c29403b93943b416c5dc5043beaf" + integrity sha512-EBX4u/uK76ikJSyoWZ2cEMj63G01w1DA68KDpSypSMhKPJE2eiCtWABRTSXhcaisq/FDwZzl4XhNjDyfzArwhA== + dependencies: + "@firebase/component" "0.5.14" + "@firebase/logger" "0.3.2" + "@firebase/performance" "0.5.9" + "@firebase/performance-types" "0.1.0" + "@firebase/util" "1.6.0" + tslib "^2.1.0" + +"@firebase/performance-types@0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@firebase/performance-types/-/performance-types-0.1.0.tgz#5e6efa9dc81860aee2cb7121b39ae8fa137e69fc" + integrity sha512-6p1HxrH0mpx+622Ql6fcxFxfkYSBpE3LSuwM7iTtYU2nw91Hj6THC8Bc8z4nboIq7WvgsT/kOTYVVZzCSlXl8w== + +"@firebase/performance@0.5.9": + version "0.5.9" + resolved "https://registry.yarnpkg.com/@firebase/performance/-/performance-0.5.9.tgz#0c911ea91c8f1e17fc67792dafed73f0a8a10b12" + integrity sha512-cA1pea1hkIZt0FG0a42tjKQNBhdY7q4apqHML92vBCS9QOOR0SHBui44IGQJRfRBGiVICHW03Q+ikSZv08g+jw== + dependencies: + "@firebase/component" "0.5.14" + "@firebase/installations" "0.5.9" + "@firebase/logger" "0.3.2" + "@firebase/util" "1.6.0" + tslib "^2.1.0" + +"@firebase/polyfill@0.3.36": + version "0.3.36" + resolved "https://registry.yarnpkg.com/@firebase/polyfill/-/polyfill-0.3.36.tgz#c057cce6748170f36966b555749472b25efdb145" + integrity sha512-zMM9oSJgY6cT2jx3Ce9LYqb0eIpDE52meIzd/oe/y70F+v9u1LDqk5kUF5mf16zovGBWMNFmgzlsh6Wj0OsFtg== + dependencies: + core-js "3.6.5" + promise-polyfill "8.1.3" + whatwg-fetch "2.0.4" + +"@firebase/remote-config-compat@0.1.9": + version "0.1.9" + resolved "https://registry.yarnpkg.com/@firebase/remote-config-compat/-/remote-config-compat-0.1.9.tgz#dfd11003ccf33d30ba61be10d6fa115f25cba025" + integrity sha512-ud4yINy8cegE82KoBDXS4fOp6qwy0+7zl0k587kMXHSWHbWVRZ/uKMQGJQc7kG0EQp0tZhM20CxVwtcCGsABBA== + dependencies: + "@firebase/component" "0.5.14" + "@firebase/logger" "0.3.2" + "@firebase/remote-config" "0.3.8" + "@firebase/remote-config-types" "0.2.0" + "@firebase/util" "1.6.0" + tslib "^2.1.0" + +"@firebase/remote-config-types@0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@firebase/remote-config-types/-/remote-config-types-0.2.0.tgz#1e2759fc01f20b58c564db42196f075844c3d1fd" + integrity sha512-hqK5sCPeZvcHQ1D6VjJZdW6EexLTXNMJfPdTwbD8NrXUw6UjWC4KWhLK/TSlL0QPsQtcKRkaaoP+9QCgKfMFPw== + +"@firebase/remote-config@0.3.8": + version "0.3.8" + resolved "https://registry.yarnpkg.com/@firebase/remote-config/-/remote-config-0.3.8.tgz#5dbbd6a39eb610b5efa0e908ec2037d3a0ca19f0" + integrity sha512-z5HYrjrgzkR25nlvQqiPowDGatlEJirA5sN1B6rOy+KYMLsb6IXLVOdKjj/Tg/uHAErwd0DblGxwBUZKTCuo1g== + dependencies: + "@firebase/component" "0.5.14" + "@firebase/installations" "0.5.9" + "@firebase/logger" "0.3.2" + "@firebase/util" "1.6.0" + tslib "^2.1.0" + +"@firebase/storage-compat@0.1.14": + version "0.1.14" + resolved "https://registry.yarnpkg.com/@firebase/storage-compat/-/storage-compat-0.1.14.tgz#a9f0c9c3fba857cf39f392bb163df813af29739e" + integrity sha512-/Fey1n+ryIeAEyd/qXPXh32ReFZUhzE5W0z/+LDA+3yyMGw/a6wCzQqe7wBiGiCRhjd+5XiV++jkCXTflun3Dg== + dependencies: + "@firebase/component" "0.5.14" + "@firebase/storage" "0.9.6" + "@firebase/storage-types" "0.6.0" + "@firebase/util" "1.6.0" + tslib "^2.1.0" + +"@firebase/storage-types@0.6.0": + version "0.6.0" + resolved "https://registry.yarnpkg.com/@firebase/storage-types/-/storage-types-0.6.0.tgz#0b1af64a2965af46fca138e5b70700e9b7e6312a" + integrity sha512-1LpWhcCb1ftpkP/akhzjzeFxgVefs6eMD2QeKiJJUGH1qOiows2w5o0sKCUSQrvrRQS1lz3SFGvNR1Ck/gqxeA== + +"@firebase/storage@0.9.6": + version "0.9.6" + resolved "https://registry.yarnpkg.com/@firebase/storage/-/storage-0.9.6.tgz#496bc8c7e6062b2efc35f8b0f26c4241302c1029" + integrity sha512-q8/s3qFbFl+AlKbyEtGA7FRVhcMu3NKPqHueBTn5XSI0B3bfxptBcDJMb9txs69ppve6P3jrK1//TEWpjTGJUg== + dependencies: + "@firebase/component" "0.5.14" + "@firebase/util" "1.6.0" + node-fetch "2.6.7" + tslib "^2.1.0" + +"@firebase/util@1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@firebase/util/-/util-1.6.0.tgz#31aea6bba3ee98fc83a60eb189cb187243f4ef4b" + integrity sha512-6+hhqb4Zzjoo12xofTDHPkgW3FnN4ydBsjd5X2KuQI268DR3W3Ld64W/gkKPZrKRgUxeNeb+pykfP3qRe7q+vA== + dependencies: + tslib "^2.1.0" + +"@firebase/webchannel-wrapper@0.6.1": + version "0.6.1" + resolved "https://registry.yarnpkg.com/@firebase/webchannel-wrapper/-/webchannel-wrapper-0.6.1.tgz#0c74724ba6e9ea6ad25a391eab60a79eaba4c556" + integrity sha512-9FqhNjKQWpQ3fGnSOCovHOm+yhhiorKEqYLAfd525jWavunDJcx8rOW6i6ozAh+FbwcYMkL7b+3j4UR/30MpoQ== + +"@grpc/grpc-js@^1.3.2": + version "1.6.7" + resolved "https://registry.yarnpkg.com/@grpc/grpc-js/-/grpc-js-1.6.7.tgz#4c4fa998ff719fe859ac19fe977fdef097bb99aa" + integrity sha512-eBM03pu9hd3VqDQG+kHahiG1x80RGkkqqRb1Pchcwqej/KkAH95gAvKs6laqaHCycYaPK+TKuNQnOz9UXYA8qw== + dependencies: + "@grpc/proto-loader" "^0.6.4" + "@types/node" ">=12.12.47" + +"@grpc/proto-loader@^0.6.0", "@grpc/proto-loader@^0.6.4": + version "0.6.12" + resolved "https://registry.yarnpkg.com/@grpc/proto-loader/-/proto-loader-0.6.12.tgz#459b619b8b9b67794bf0d1cb819653a38c63e164" + integrity sha512-filTVbETFnxb9CyRX98zN18ilChTuf/C5scZ2xyaOTp0EHGq0/ufX8rjqXUcSb1Gpv7eZq4M2jDvbh9BogKnrg== + dependencies: + "@types/long" "^4.0.1" + lodash.camelcase "^4.3.0" + long "^4.0.0" + protobufjs "^6.10.0" + yargs "^16.2.0" + "@hapi/hoek@^9.0.0": version "9.2.0" resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.2.0.tgz#f3933a44e365864f4dad5db94158106d511e8131" @@ -2589,6 +3021,59 @@ resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.9.2.tgz#adea7b6953cbb34651766b0548468e743c6a2353" integrity sha512-VZMYa7+fXHdwIq1TDhSXoVmSPEGM/aa+6Aiq3nVVJ9bXr24zScr+NlKFKC3iPljA7ho/GAZr+d2jOf5GIRC30Q== +"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" + integrity sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ== + +"@protobufjs/base64@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" + integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== + +"@protobufjs/codegen@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" + integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== + +"@protobufjs/eventemitter@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" + integrity sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q== + +"@protobufjs/fetch@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" + integrity sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ== + dependencies: + "@protobufjs/aspromise" "^1.1.1" + "@protobufjs/inquire" "^1.1.0" + +"@protobufjs/float@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" + integrity sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ== + +"@protobufjs/inquire@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" + integrity sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q== + +"@protobufjs/path@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" + integrity sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA== + +"@protobufjs/pool@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" + integrity sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw== + +"@protobufjs/utf8@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" + integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw== + "@redux-saga/core@^1.1.3": version "1.1.3" resolved "https://registry.yarnpkg.com/@redux-saga/core/-/core-1.1.3.tgz#3085097b57a4ea8db5528d58673f20ce0950f6a4" @@ -3331,6 +3816,11 @@ resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.178.tgz#341f6d2247db528d4a13ddbb374bcdc80406f4f8" integrity sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw== +"@types/long@^4.0.1": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.2.tgz#b74129719fc8d11c01868010082d483b7545591a" + integrity sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA== + "@types/mdast@^3.0.0": version "3.0.3" resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.3.tgz#2d7d671b1cd1ea3deb306ea75036c2a0407d2deb" @@ -3361,6 +3851,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-13.13.45.tgz#e6676bcca092bae5751d015f074a234d5a82eb63" integrity sha512-703YTEp8AwQeapI0PTXDOj+Bs/mtdV/k9VcTP7z/de+lx6XjFMKdB+JhKnK+6PZ5za7omgZ3V6qm/dNkMj/Zow== +"@types/node@>=12.12.47", "@types/node@>=13.7.0": + version "17.0.38" + resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.38.tgz#f8bb07c371ccb1903f3752872c89f44006132947" + integrity sha512-5jY9RhV7c0Z4Jy09G+NIDTsCZ5G0L5n+Z+p+Y7t5VJHM30bgwzSjVtlcBxqAj+6L/swIlvtOSzr8rBk/aNyV2g== + "@types/node@^12.12.6": version "12.20.4" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.4.tgz#73687043dd00fcb6962c60fbf499553a24d6bdf2" @@ -4451,6 +4946,17 @@ babel-plugin-polyfill-regenerator@^0.2.0: babel-plugin-syntax-jsx "^6.18.0" lodash "^4.17.11" +"babel-plugin-styled-components@>= 1.12.0": + version "2.0.7" + resolved "https://registry.yarnpkg.com/babel-plugin-styled-components/-/babel-plugin-styled-components-2.0.7.tgz#c81ef34b713f9da2b7d3f5550df0d1e19e798086" + integrity sha512-i7YhvPgVqRKfoQ66toiZ06jPNA3p6ierpfUuEWxNF+fV27Uv5gxBkf8KZLHUCc1nFA9j6+80pYoIpqCeyW3/bA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.0" + "@babel/helper-module-imports" "^7.16.0" + babel-plugin-syntax-jsx "^6.18.0" + lodash "^4.17.11" + picomatch "^2.3.0" + 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" @@ -5532,6 +6038,11 @@ core-js-pure@^3.0.0: resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.9.1.tgz#677b322267172bd490e4464696f790cbc355bec5" integrity sha512-laz3Zx0avrw9a4QEIdmIblnVuJz8W51leY9iLThatCsFawWxC3sE4guASC78JbCin+DkwMpCdp1AVAuzL/GN7A== +core-js@3.6.5: + version "3.6.5" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.6.5.tgz#7395dc273af37fb2e50e9bd3d9fe841285231d1a" + integrity sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA== + core-js@^2.4.0: version "2.6.12" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" @@ -7384,6 +7895,13 @@ fastq@^1.6.0: dependencies: reusify "^1.0.4" +faye-websocket@0.11.4: + version "0.11.4" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" + integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== + dependencies: + websocket-driver ">=0.5.1" + faye-websocket@^0.11.3: version "0.11.3" resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.3.tgz#5c0e9a8968e8912c286639fde977a8b209f2508e" @@ -7554,6 +8072,38 @@ findup-sync@^3.0.0: micromatch "^3.0.4" resolve-dir "^1.0.1" +firebase@^9.6.11: + version "9.8.2" + resolved "https://registry.yarnpkg.com/firebase/-/firebase-9.8.2.tgz#ce2b8a6d41036b323d963280c345b03f4bd4df52" + integrity sha512-cVPpiR18vsLuGWAAVkVhNO6mYsEgYBqawvMI2zxKo2FCtneyBgMwOyWKI8VyCmL5ze5p5QJTPjkoatM6rZkd0Q== + dependencies: + "@firebase/analytics" "0.7.9" + "@firebase/analytics-compat" "0.1.10" + "@firebase/app" "0.7.25" + "@firebase/app-check" "0.5.8" + "@firebase/app-check-compat" "0.2.8" + "@firebase/app-compat" "0.1.26" + "@firebase/app-types" "0.7.0" + "@firebase/auth" "0.20.2" + "@firebase/auth-compat" "0.2.15" + "@firebase/database" "0.13.0" + "@firebase/database-compat" "0.2.0" + "@firebase/firestore" "3.4.9" + "@firebase/firestore-compat" "0.1.18" + "@firebase/functions" "0.8.1" + "@firebase/functions-compat" "0.2.1" + "@firebase/installations" "0.5.9" + "@firebase/messaging" "0.9.13" + "@firebase/messaging-compat" "0.1.13" + "@firebase/performance" "0.5.9" + "@firebase/performance-compat" "0.1.9" + "@firebase/polyfill" "0.3.36" + "@firebase/remote-config" "0.3.8" + "@firebase/remote-config-compat" "0.1.9" + "@firebase/storage" "0.9.6" + "@firebase/storage-compat" "0.1.14" + "@firebase/util" "1.6.0" + flat-cache@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" @@ -8541,6 +9091,11 @@ icss-utils@^4.0.0, icss-utils@^4.1.1: dependencies: postcss "^7.0.14" +idb@7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/idb/-/idb-7.0.1.tgz#d2875b3a2f205d854ee307f6d196f246fea590a7" + integrity sha512-UUxlE7vGWK5RfB/fDwEGgRf84DY/ieqNha6msMV99UsEMQhJ1RwbCd8AYBj3QMgnE3VZnfQvm4oKVCJTYlqIgg== + ieee754@^1.1.13: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" @@ -8568,6 +9123,11 @@ ignore@^5.1.1, ignore@^5.1.4: resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== +immediate@~3.0.5: + version "3.0.6" + resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" + integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ== + immer@^9.0.6: version "9.0.6" resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.6.tgz#7a96bf2674d06c8143e327cbf73539388ddf1a73" @@ -10229,6 +10789,16 @@ jsprim@^1.2.2: array-includes "^3.1.2" object.assign "^4.1.2" +jszip@^3.6.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.10.0.tgz#faf3db2b4b8515425e34effcdbb086750a346061" + integrity sha512-LDfVtOLtOxb9RXkYOwPyNBTQDL4eUbqahtoY6x07GiDJHwSYvn8sHHIw8wINImV3MqbMNve2gSuM1DDqEKk09Q== + dependencies: + lie "~3.3.0" + pako "~1.0.2" + readable-stream "~2.3.6" + setimmediate "^1.0.5" + jwa@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/jwa/-/jwa-2.0.0.tgz#a7e9c3f29dae94027ebcaf49975c9345593410fc" @@ -10342,6 +10912,13 @@ levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" +lie@~3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/lie/-/lie-3.3.0.tgz#dcf82dee545f46074daf200c7c1c5a08e0f40f6a" + integrity sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ== + dependencies: + immediate "~3.0.5" + lines-and-columns@^1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" @@ -10471,6 +11048,11 @@ lodash._reinterpolate@^3.0.0: resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= +lodash.camelcase@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" + integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA== + lodash.clonedeep@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" @@ -10580,6 +11162,11 @@ lolex@^5.0.0: dependencies: "@sinonjs/commons" "^1.7.0" +long@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" + integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== + longest-streak@^2.0.0, longest-streak@^2.0.1: version "2.0.4" resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-2.0.4.tgz#b8599957da5b5dab64dee3fe316fa774597d90e4" @@ -11951,6 +12538,11 @@ p-waterfall@^1.0.0: dependencies: p-reduce "^1.0.0" +pako@~1.0.2: + version "1.0.11" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" + integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== + papaparse@^5.3.0, papaparse@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/papaparse/-/papaparse-5.3.1.tgz#770b7a9124d821d4b2132132b7bd7dce7194b5b1" @@ -12171,6 +12763,11 @@ picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== +picomatch@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + pidtree@^0.3.0: version "0.3.1" resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.3.1.tgz#ef09ac2cc0533df1f3250ccf2c4d366b0d12114a" @@ -12419,6 +13016,11 @@ promise-inflight@^1.0.1: resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= +promise-polyfill@8.1.3: + version "8.1.3" + resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-8.1.3.tgz#8c99b3cf53f3a91c68226ffde7bde81d7f904116" + integrity sha512-MG5r82wBzh7pSKDRa9y+vllNHz3e3d4CNj1PQE4BQYxLme0gKYYBm9YENq+UkEikyZ0XbiGWxYlVw3Rl9O/U8g== + promise-retry@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-1.1.1.tgz#6739e968e3051da20ce6497fb2b50f6911df3d6d" @@ -12472,6 +13074,25 @@ proto-list@~1.2.1: resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk= +protobufjs@^6.10.0: + version "6.11.3" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.11.3.tgz#637a527205a35caa4f3e2a9a4a13ddffe0e7af74" + integrity sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg== + dependencies: + "@protobufjs/aspromise" "^1.1.2" + "@protobufjs/base64" "^1.1.2" + "@protobufjs/codegen" "^2.0.4" + "@protobufjs/eventemitter" "^1.1.0" + "@protobufjs/fetch" "^1.1.0" + "@protobufjs/float" "^1.0.2" + "@protobufjs/inquire" "^1.1.0" + "@protobufjs/path" "^1.1.2" + "@protobufjs/pool" "^1.1.0" + "@protobufjs/utf8" "^1.1.0" + "@types/long" "^4.0.1" + "@types/node" ">=13.7.0" + long "^4.0.0" + protocols@^1.1.0, protocols@^1.4.0: version "1.4.8" resolved "https://registry.yarnpkg.com/protocols/-/protocols-1.4.8.tgz#48eea2d8f58d9644a4a32caae5d5db290a075ce8" @@ -12681,7 +13302,7 @@ react-diff-viewer@^3.1.1: memoize-one "^5.0.4" prop-types "^15.6.2" -react-dom@^16.13.1: +react-dom@^16.13.1, react-dom@^16.14.0: version "16.14.0" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.14.0.tgz#7ad838ec29a777fb3c75c3a190f661cf92ab8b89" integrity sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw== @@ -12814,6 +13435,19 @@ react-router-dom@^5.1.2, react-router-dom@^5.2.0: tiny-invariant "^1.0.2" tiny-warning "^1.0.0" +react-router-dom@^5.3.0: + version "5.3.3" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.3.3.tgz#8779fc28e6691d07afcaf98406d3812fe6f11199" + integrity sha512-Ov0tGPMBgqmbu5CDmN++tv2HQ9HlWDuWIIqn4b88gjlAN5IHI+4ZUZRcpz9Hl0azFIwihbLDYw1OiHGRo7ZIng== + dependencies: + "@babel/runtime" "^7.12.13" + history "^4.9.0" + loose-envify "^1.3.1" + prop-types "^15.6.2" + react-router "5.3.3" + tiny-invariant "^1.0.2" + tiny-warning "^1.0.0" + react-router@5.2.0, react-router@^5.1.2: version "5.2.0" resolved "https://registry.yarnpkg.com/react-router/-/react-router-5.2.0.tgz#424e75641ca8747fbf76e5ecca69781aa37ea293" @@ -12830,6 +13464,22 @@ react-router@5.2.0, react-router@^5.1.2: tiny-invariant "^1.0.2" tiny-warning "^1.0.0" +react-router@5.3.3: + version "5.3.3" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-5.3.3.tgz#8e3841f4089e728cf82a429d92cdcaa5e4a3a288" + integrity sha512-mzQGUvS3bM84TnbtMYR8ZjKnuPJ71IjSzR+DE6UkUqvN4czWIqEs17yLL8xkAycv4ev0AiN+IGrWu88vJs/p2w== + dependencies: + "@babel/runtime" "^7.12.13" + history "^4.9.0" + hoist-non-react-statics "^3.1.0" + loose-envify "^1.3.1" + mini-create-react-context "^0.4.0" + path-to-regexp "^1.7.0" + prop-types "^15.6.2" + react-is "^16.6.0" + tiny-invariant "^1.0.2" + tiny-warning "^1.0.0" + react-shallow-renderer@^16.13.1: version "16.14.1" resolved "https://registry.yarnpkg.com/react-shallow-renderer/-/react-shallow-renderer-16.14.1.tgz#bf0d02df8a519a558fd9b8215442efa5c840e124" @@ -12863,7 +13513,7 @@ react-test-renderer@^17.0.1: react-shallow-renderer "^16.13.1" scheduler "^0.20.1" -react@^16.13.1: +react@^16.13.1, react@^16.14.0: version "16.14.0" resolved "https://registry.yarnpkg.com/react/-/react-16.14.0.tgz#94d776ddd0aaa37da3eda8fc5b6b18a4c9a3114d" integrity sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g== @@ -12880,6 +13530,14 @@ react@^17.0.2: loose-envify "^1.1.0" object-assign "^4.1.1" +reactfire@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/reactfire/-/reactfire-4.2.1.tgz#48bbd2408247e930658bff58d94863b759381d9a" + integrity sha512-wWATeAPnGmp44rkG+0F2788HnVNgsk0H1vYimeNnNa/RouzkOn58vJmYgKyQhWAOmZl9Smkx9bDsFlt3PevN0w== + dependencies: + rxfire "^6.0.2" + rxjs "^6.6.3 || ^7.0.1" + read-cmd-shim@^1.0.1: version "1.0.5" resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-1.0.5.tgz#87e43eba50098ba5a32d0ceb583ab8e43b961c16" @@ -13546,6 +14204,13 @@ rw@1: resolved "https://registry.yarnpkg.com/rw/-/rw-1.3.3.tgz#3f862dfa91ab766b14885ef4d01124bfda074fb4" integrity sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q= +rxfire@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/rxfire/-/rxfire-6.0.3.tgz#556a08e5276563c867daeb8c670f59363d212365" + integrity sha512-77nkyffHh7jgfi1YA/N9RI+kWxYpgKk6GRML1lyersvaqbJt4hkvWwk1rWib9Rb5Lr5mT+Ha45lu7nM79sJCZA== + dependencies: + tslib "^1.9.0 || ~2.1.0" + rxjs@6.6.6, rxjs@^6.4.0, rxjs@^6.5.2, rxjs@^6.6.0, rxjs@^6.6.3, rxjs@^6.6.6: version "6.6.6" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.6.tgz#14d8417aa5a07c5e633995b525e1e3c0dec03b70" @@ -13553,6 +14218,13 @@ rxjs@6.6.6, rxjs@^6.4.0, rxjs@^6.5.2, rxjs@^6.6.0, rxjs@^6.6.3, rxjs@^6.6.6: dependencies: tslib "^1.9.0" +"rxjs@^6.6.3 || ^7.0.1": + version "7.5.5" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.5.tgz#2ebad89af0f560f460ad5cc4213219e1f7dd4e9f" + integrity sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw== + dependencies: + tslib "^2.1.0" + safe-buffer@*, safe-buffer@5.1.2, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" @@ -13652,6 +14324,15 @@ select-hose@^2.0.0: resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= +selenium-webdriver@4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-4.1.2.tgz#d463b4335632d2ea41a9e988e435a55dc41f5314" + integrity sha512-e4Ap8vQvhipgBB8Ry9zBiKGkU6kHKyNnWiavGGLKkrdW81Zv7NVMtFOL/j3yX0G8QScM7XIXijKssNd4EUxSOw== + dependencies: + jszip "^3.6.0" + tmp "^0.2.1" + ws ">=7.4.6" + selfsigned@^1.10.8: version "1.10.8" resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.8.tgz#0d17208b7d12c33f8eac85c41835f27fc3d81a30" @@ -13750,6 +14431,11 @@ set-value@^2.0.0, set-value@^2.0.1: is-plain-object "^2.0.3" split-string "^3.0.1" +setimmediate@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= + setprototypeof@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" @@ -14491,6 +15177,22 @@ styled-components@^5.2.1: shallowequal "^1.1.0" supports-color "^5.5.0" +styled-components@^5.3.1: + version "5.3.5" + resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.3.5.tgz#a750a398d01f1ca73af16a241dec3da6deae5ec4" + integrity sha512-ndETJ9RKaaL6q41B69WudeqLzOpY1A/ET/glXkNZ2T7dPjPqpPCXXQjDFYZWwNnE5co0wX+gTCqx9mfxTmSIPg== + dependencies: + "@babel/helper-module-imports" "^7.0.0" + "@babel/traverse" "^7.4.5" + "@emotion/is-prop-valid" "^1.1.0" + "@emotion/stylis" "^0.8.4" + "@emotion/unitless" "^0.7.4" + babel-plugin-styled-components ">= 1.12.0" + css-to-react-native "^3.0.0" + hoist-non-react-statics "^3.0.0" + shallowequal "^1.1.0" + supports-color "^5.5.0" + styled-system@^5.1.2, styled-system@^5.1.5: version "5.1.5" resolved "https://registry.yarnpkg.com/styled-system/-/styled-system-5.1.5.tgz#e362d73e1dbb5641a2fd749a6eba1263dc85075e" @@ -14774,6 +15476,13 @@ tmp@^0.0.33: dependencies: os-tmpdir "~1.0.2" +tmp@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" + integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== + dependencies: + rimraf "^3.0.0" + tmpl@1.0.x: version "1.0.5" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" @@ -14941,11 +15650,16 @@ tslib@1.13.0, tslib@^1.8.1, tslib@^1.9.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043" integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q== -tslib@2.1.0: +tslib@2.1.0, "tslib@^1.9.0 || ~2.1.0": version "2.1.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a" integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A== +tslib@^2.1.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" + integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== + tslib@^2.3.0, tslib@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" @@ -15702,6 +16416,11 @@ whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.5: dependencies: iconv-lite "0.4.24" +whatwg-fetch@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" + integrity sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng== + whatwg-mimetype@^2.2.0, whatwg-mimetype@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" @@ -15882,7 +16601,7 @@ write-pkg@^3.1.0: sort-keys "^2.0.0" write-json-file "^2.2.0" -ws@7.4.6, "ws@>= 7.4.6", ws@^6.2.1, ws@^7.0.0, ws@^7.2.3, ws@^7.3.1: +ws@7.4.6, "ws@>= 7.4.6", ws@>=7.4.6, ws@^6.2.1, ws@^7.0.0, ws@^7.2.3, ws@^7.3.1: version "8.5.0" resolved "https://registry.yarnpkg.com/ws/-/ws-8.5.0.tgz#bfb4be96600757fe5382de12c670dab984a1ed4f" integrity sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg== @@ -16016,7 +16735,7 @@ yargs@^15.3.1, yargs@^15.4.1: y18n "^4.0.0" yargs-parser "^18.1.2" -yargs@^16.1.1: +yargs@^16.1.1, yargs@^16.2.0: version "16.2.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==