From f2fa650c9280c317926a2051218a354167032d51 Mon Sep 17 00:00:00 2001 From: James Coon Date: Wed, 8 Feb 2023 10:23:28 -0500 Subject: [PATCH 1/3] DEV-1300: Update MX README to include details surround MX Bank versus MX Bank (OAuth) (#15) --- packages/mx-token-exchange/README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/mx-token-exchange/README.md b/packages/mx-token-exchange/README.md index 6d9f802..ab02020 100644 --- a/packages/mx-token-exchange/README.md +++ b/packages/mx-token-exchange/README.md @@ -9,4 +9,8 @@ This example project, built using [Next.js](https://nextjs.org), demonstrates ho 1. Create a [Dwolla Sandbox Account](https://accounts-sandbox.dwolla.com/sign-up) and an [MX Account](https://dashboard.mx.com/sign_up). 2. Rename `.env.local.example` to `.env.local`, and enter the necessary access keys for both Dwolla and MX. 3. Run `pnpm install` to download all necessary dependencies. -4. Run `pnpm dev` to start the Next.js application! \ No newline at end of file +4. Run `pnpm dev` to start the Next.js application! (Before connecting a bank account, please see _[Using MX Connect](#using-mx-connect)_.) + +## Using MX Connect + +When using MX Web Widget SDK to connect a bank account, there are two development options present: MX Bank and MX Bank (OAuth). To integrate with Dwolla's token exchange service, please use the latter: [MX Bank (OAuth)](https://docs.mx.com/testing/guides/testing#test_oauth). Using MX Bank and supplying test credentials does not work at this time. \ No newline at end of file From 3252d91c822752fc98a34a6377ee8901db1d3689 Mon Sep 17 00:00:00 2001 From: James Coon Date: Fri, 24 Feb 2023 14:51:00 -0600 Subject: [PATCH 2/3] DEV-1302: Update MX endpoint to use /authorization_code instead of /payment_processor_authorization_code (#16) --- packages/mx-token-exchange/src/integrations/mx.ts | 14 ++++++-------- .../mx-token-exchange/src/pages/connect-mx.tsx | 2 +- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/packages/mx-token-exchange/src/integrations/mx.ts b/packages/mx-token-exchange/src/integrations/mx.ts index 43f465d..482b586 100644 --- a/packages/mx-token-exchange/src/integrations/mx.ts +++ b/packages/mx-token-exchange/src/integrations/mx.ts @@ -22,11 +22,11 @@ export interface RequestAuthorizationCodeOptions { } export interface RequestAuthorizationCodeResponse { - readonly authorization_code?: string; + readonly code?: string; } export interface RequestAuthorizationCodeResponseBody { - readonly payment_processor_authorization_code: RequestAuthorizationCodeResponse; + readonly authorization_code: RequestAuthorizationCodeResponse; } const ACCEPT_HEADER = "application/vnd.mx.api.v1+json"; @@ -104,12 +104,10 @@ export async function requestAuthorizationCode( ): Promise { return ( await client["axios"].post( - "/payment_processor_authorization_code", + "/authorization_code", { - payment_processor_authorization_code: { - account_guid: options.accountGuid, - member_guid: options.memberGuid, - user_guid: options.userGuid + authorization_code: { + scope: `account-guid:${options.accountGuid} member-guid:${options.memberGuid} user-guid:${options.userGuid} read-protected` } }, { @@ -124,5 +122,5 @@ export async function requestAuthorizationCode( } } ) - ).data.payment_processor_authorization_code; + ).data.authorization_code; } diff --git a/packages/mx-token-exchange/src/pages/connect-mx.tsx b/packages/mx-token-exchange/src/pages/connect-mx.tsx index 4b0a5d6..4121c86 100644 --- a/packages/mx-token-exchange/src/pages/connect-mx.tsx +++ b/packages/mx-token-exchange/src/pages/connect-mx.tsx @@ -72,7 +72,7 @@ export const ConnectMxPage: NextPage = ({ widgetUrl }) => { }); if (!response.ok) return undefined; - return ((await response.json()) as MXProcessorTokenAPIResponse).token?.authorization_code; + return ((await response.json()) as MXProcessorTokenAPIResponse).token?.code; } /** From da3f34ee939fe5c20c06e0e63d9d78e1934903cb Mon Sep 17 00:00:00 2001 From: Joey Hage <3220319+joeyhage@users.noreply.github.com> Date: Thu, 25 May 2023 11:43:19 -0500 Subject: [PATCH 3/3] Add Flinks example (#17) Co-authored-by: Joey Hage Co-authored-by: James Coon --- README.md | 3 +- .../flinks-token-exchange/.env.local.example | 11 + packages/flinks-token-exchange/.gitignore | 36 + packages/flinks-token-exchange/README.md | 16 + packages/flinks-token-exchange/next.config.js | 6 + packages/flinks-token-exchange/package.json | 43 + packages/flinks-token-exchange/pnpm-lock.yaml | 1511 +++++++++++++++++ .../src/createEmotionCache.ts | 10 + .../src/hooks/useFlinksConnect.ts | 30 + .../src/hooks/useNetworkAlert.ts | 44 + .../src/integrations/dwolla.ts | 97 ++ .../src/integrations/flinks.ts | 136 ++ .../src/integrations/index.ts | 5 + .../src/layouts/MainLayout.tsx | 29 + .../flinks-token-exchange/src/pages/_app.tsx | 30 + .../src/pages/_document.tsx | 57 + .../src/pages/api/dwolla/customers.ts | 27 + .../src/pages/api/dwolla/exchanges.ts | 27 + .../src/pages/api/dwolla/funding-sources.ts | 27 + .../src/pages/api/flinks/access-token.ts | 21 + .../src/pages/api/flinks/accounts-summary.ts | 21 + .../src/pages/api/flinks/auth-secret.ts | 21 + .../src/pages/api/flinks/request-id.ts | 21 + .../src/pages/connect-exchange.tsx | 227 +++ .../src/pages/connect-flinks.tsx | 265 +++ .../src/pages/create-customers.tsx | 160 ++ .../flinks-token-exchange/src/pages/index.tsx | 14 + packages/flinks-token-exchange/src/theme.ts | 16 + .../src/utils/assertRequestMethod.ts | 16 + .../src/utils/assertValidBody.ts | 21 + .../src/utils/equalsIgnoreCase.ts | 7 + .../src/utils/getMissingKeys.ts | 6 + .../flinks-token-exchange/src/utils/index.ts | 6 + .../src/utils/tryNextResponse.ts | 13 + .../src/utils/uuidFromUrl.ts | 7 + packages/flinks-token-exchange/tsconfig.json | 5 + pnpm-lock.yaml | 626 +++---- 37 files changed, 3322 insertions(+), 296 deletions(-) create mode 100644 packages/flinks-token-exchange/.env.local.example create mode 100644 packages/flinks-token-exchange/.gitignore create mode 100644 packages/flinks-token-exchange/README.md create mode 100644 packages/flinks-token-exchange/next.config.js create mode 100644 packages/flinks-token-exchange/package.json create mode 100644 packages/flinks-token-exchange/pnpm-lock.yaml create mode 100644 packages/flinks-token-exchange/src/createEmotionCache.ts create mode 100644 packages/flinks-token-exchange/src/hooks/useFlinksConnect.ts create mode 100644 packages/flinks-token-exchange/src/hooks/useNetworkAlert.ts create mode 100644 packages/flinks-token-exchange/src/integrations/dwolla.ts create mode 100644 packages/flinks-token-exchange/src/integrations/flinks.ts create mode 100644 packages/flinks-token-exchange/src/integrations/index.ts create mode 100644 packages/flinks-token-exchange/src/layouts/MainLayout.tsx create mode 100644 packages/flinks-token-exchange/src/pages/_app.tsx create mode 100644 packages/flinks-token-exchange/src/pages/_document.tsx create mode 100644 packages/flinks-token-exchange/src/pages/api/dwolla/customers.ts create mode 100644 packages/flinks-token-exchange/src/pages/api/dwolla/exchanges.ts create mode 100644 packages/flinks-token-exchange/src/pages/api/dwolla/funding-sources.ts create mode 100644 packages/flinks-token-exchange/src/pages/api/flinks/access-token.ts create mode 100644 packages/flinks-token-exchange/src/pages/api/flinks/accounts-summary.ts create mode 100644 packages/flinks-token-exchange/src/pages/api/flinks/auth-secret.ts create mode 100644 packages/flinks-token-exchange/src/pages/api/flinks/request-id.ts create mode 100644 packages/flinks-token-exchange/src/pages/connect-exchange.tsx create mode 100644 packages/flinks-token-exchange/src/pages/connect-flinks.tsx create mode 100644 packages/flinks-token-exchange/src/pages/create-customers.tsx create mode 100644 packages/flinks-token-exchange/src/pages/index.tsx create mode 100644 packages/flinks-token-exchange/src/theme.ts create mode 100644 packages/flinks-token-exchange/src/utils/assertRequestMethod.ts create mode 100644 packages/flinks-token-exchange/src/utils/assertValidBody.ts create mode 100644 packages/flinks-token-exchange/src/utils/equalsIgnoreCase.ts create mode 100644 packages/flinks-token-exchange/src/utils/getMissingKeys.ts create mode 100644 packages/flinks-token-exchange/src/utils/index.ts create mode 100644 packages/flinks-token-exchange/src/utils/tryNextResponse.ts create mode 100644 packages/flinks-token-exchange/src/utils/uuidFromUrl.ts create mode 100644 packages/flinks-token-exchange/tsconfig.json diff --git a/README.md b/README.md index e941807..0b25bd0 100644 --- a/README.md +++ b/README.md @@ -16,4 +16,5 @@ To get more information on installing and running a specific app, please click o * [Finicity](https://github.com/Dwolla/integration-examples/tree/main/packages/finicity-token-exchange#readme) * [Plaid](https://github.com/Dwolla/integration-examples/tree/main/packages/plaid-funding-source#readme) -* [MX](https://github.com/Dwolla/integration-examples/tree/main/packages/mx-token-exchange#readme) \ No newline at end of file +* [MX](https://github.com/Dwolla/integration-examples/tree/main/packages/mx-token-exchange#readme) +* [Flinks](https://github.com/Dwolla/integration-examples/tree/main/packages/flinks-token-exchange#readme) \ No newline at end of file diff --git a/packages/flinks-token-exchange/.env.local.example b/packages/flinks-token-exchange/.env.local.example new file mode 100644 index 0000000..d23d4e3 --- /dev/null +++ b/packages/flinks-token-exchange/.env.local.example @@ -0,0 +1,11 @@ +# Dwolla Environment and Client Key and Secret +# https://dashboard-sandbox.dwolla.com/applications-legacy +DWOLLA_ENV=sandbox +DWOLLA_KEY= +DWOLLA_SECRET= + +# Flinks Instance, Customer ID, and API Secret +# Contact Flinks (https://flinks.com/contact/sales/) for more information on how to obtained these values +FLINKS_INSTANCE=toolbox +FLINKS_CUSTOMER_ID= +FLINKS_API_SECRET= \ No newline at end of file diff --git a/packages/flinks-token-exchange/.gitignore b/packages/flinks-token-exchange/.gitignore new file mode 100644 index 0000000..c87c9b3 --- /dev/null +++ b/packages/flinks-token-exchange/.gitignore @@ -0,0 +1,36 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# local env files +.env*.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/packages/flinks-token-exchange/README.md b/packages/flinks-token-exchange/README.md new file mode 100644 index 0000000..093f1a2 --- /dev/null +++ b/packages/flinks-token-exchange/README.md @@ -0,0 +1,16 @@ +# Dwolla and Flinks - Token Exchange + +This example project, built using [Next.js](https://nextjs.org), demonstrates how a Funding Source can be created for a Dwolla Customer using Dwolla's integration with Flinks via Dwolla's Token Exchange. By doing this, Dwolla is able to instantly verify the Funding Source without the need for your application to transmit sensitive data. (All sensitive data is retrieved directly from Flinks by Dwolla.) + +**Note**: Since this project depends on shared dependencies, please ensure that you have executed `pnpm install` in the root directory (`integration-examples`) before continuing. + +## Setup + +1. Create a [Dwolla Sandbox Account](https://accounts-sandbox.dwolla.com/sign-up) and a [Flinks Account](https://docs.flinks.com/docs/welcome). +2. Rename `.env.local.example` to `.env.local`, and enter the necessary access keys for both Dwolla and Flinks. +3. Run `pnpm install` to download all necessary dependencies. +4. Run `pnpm dev` to start the Next.js application! (Before connecting a bank account, please see _[Using Flinks Connect](#using-flinks-connect)_.) + +## Using Flinks Connect + +When using Flinks Connect in a development environment, search for Flinks Capital and enter username `jane_doe_2_accounts` and password `Everyday`. This username and password combination results in a dummy Flinks account that has a valid US routing number. Other username and password combinations with Flinks Capital may not work in Dwolla's Sandbox environment. For more information, please [see Test Institution on Flinks' website](https://docs.flinks.com/docs/test-institution). diff --git a/packages/flinks-token-exchange/next.config.js b/packages/flinks-token-exchange/next.config.js new file mode 100644 index 0000000..31fee26 --- /dev/null +++ b/packages/flinks-token-exchange/next.config.js @@ -0,0 +1,6 @@ +/** @type {import("next").NextConfig} */ +const nextConfig = { + swcMinify: true +}; + +module.exports = nextConfig; diff --git a/packages/flinks-token-exchange/package.json b/packages/flinks-token-exchange/package.json new file mode 100644 index 0000000..9161a2d --- /dev/null +++ b/packages/flinks-token-exchange/package.json @@ -0,0 +1,43 @@ +{ + "name": "@example/flinks-token-exchange", + "version": "1.0.0", + "description": "Dwolla integration example that uses the Secure Token Exchange to verify a customer's bank account using Flinks", + "license": "MIT", + "author": "Dwolla, Inc.", + "scripts": { + "build": "next build", + "checks": "../../node_modules/.bin/tsc --pretty --noEmit && pnpm lint && pnpm prettier:check", + "clean": "../../node_modules/.bin/rimraf \"{.next,node_modules,tsconfig.tsbuildinfo}\"", + "dev": "next dev", + "format": "../../node_modules/.bin/prettier --config ../../.prettierrc.json --write \"src/**/*.+(ts|tsx)\"", + "lint": "next lint --config ../../.eslintrc.json", + "lint:fix": "next lint --config ../../.eslintrc.json --fix", + "prettier:check": "../../node_modules/.bin/prettier --check --config ../../.prettierrc.json \"src/**/*.+(ts|tsx)\"", + "prettier:write": "../../node_modules/.bin/prettier --config ../../.prettierrc.json \"src/**/*.+(ts|tsx)\" --write", + "start": "next start" + }, + "devDependencies": { + "@babel/core": "^7.19.3", + "@types/node": "18.8.3", + "@types/react": "18.0.21", + "@types/react-dom": "18.0.6", + "@types/uuid": "^8.3.4" + }, + "dependencies": { + "@emotion/cache": "^11.10.3", + "@emotion/react": "^11.10.4", + "@emotion/server": "^11.10.0", + "@emotion/styled": "^11.10.4", + "@mui/icons-material": "^5.10.6", + "@mui/lab": "5.0.0-alpha.102", + "@mui/material": "^5.10.8", + "axios": "^0.27.2", + "dwolla-v2": "4.0.0-ts-alpha.0", + "form-data": "^4.0.0", + "next": "12.3.1", + "react": "18.2.0", + "react-dom": "18.2.0", + "usehooks-ts": "^2.9.1", + "uuid": "^9.0.0" + } +} diff --git a/packages/flinks-token-exchange/pnpm-lock.yaml b/packages/flinks-token-exchange/pnpm-lock.yaml new file mode 100644 index 0000000..3b6ca0e --- /dev/null +++ b/packages/flinks-token-exchange/pnpm-lock.yaml @@ -0,0 +1,1511 @@ +lockfileVersion: '6.0' + +dependencies: + '@emotion/cache': + specifier: ^11.10.3 + version: 11.10.3 + '@emotion/react': + specifier: ^11.10.4 + version: 11.10.4(@babel/core@7.19.3)(@types/react@18.0.21)(react@18.2.0) + '@emotion/server': + specifier: ^11.10.0 + version: 11.10.0 + '@emotion/styled': + specifier: ^11.10.4 + version: 11.10.4(@babel/core@7.19.3)(@emotion/react@11.10.4)(@types/react@18.0.21)(react@18.2.0) + '@mui/icons-material': + specifier: ^5.10.6 + version: 5.10.6(@mui/material@5.10.8)(@types/react@18.0.21)(react@18.2.0) + '@mui/lab': + specifier: 5.0.0-alpha.102 + version: 5.0.0-alpha.102(@emotion/react@11.10.4)(@emotion/styled@11.10.4)(@mui/material@5.10.8)(@types/react@18.0.21)(react-dom@18.2.0)(react@18.2.0) + '@mui/material': + specifier: ^5.10.8 + version: 5.10.8(@emotion/react@11.10.4)(@emotion/styled@11.10.4)(@types/react@18.0.21)(react-dom@18.2.0)(react@18.2.0) + axios: + specifier: ^0.27.2 + version: 0.27.2 + dwolla-v2: + specifier: 4.0.0-ts-alpha.0 + version: 4.0.0-ts-alpha.0(form-data@4.0.0) + form-data: + specifier: ^4.0.0 + version: 4.0.0 + next: + specifier: 12.3.1 + version: 12.3.1(@babel/core@7.19.3)(react-dom@18.2.0)(react@18.2.0) + react: + specifier: 18.2.0 + version: 18.2.0 + react-dom: + specifier: 18.2.0 + version: 18.2.0(react@18.2.0) + usehooks-ts: + specifier: ^2.9.1 + version: 2.9.1(react-dom@18.2.0)(react@18.2.0) + uuid: + specifier: ^9.0.0 + version: 9.0.0 + +devDependencies: + '@babel/core': + specifier: ^7.19.3 + version: 7.19.3 + '@types/node': + specifier: 18.8.3 + version: 18.8.3 + '@types/react': + specifier: 18.0.21 + version: 18.0.21 + '@types/react-dom': + specifier: 18.0.6 + version: 18.0.6 + '@types/uuid': + specifier: ^8.3.4 + version: 8.3.4 + +packages: + + /@ampproject/remapping@2.2.0: + resolution: {integrity: sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/gen-mapping': 0.1.1 + '@jridgewell/trace-mapping': 0.3.15 + + /@babel/code-frame@7.18.6: + resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/highlight': 7.18.6 + + /@babel/compat-data@7.19.3: + resolution: {integrity: sha512-prBHMK4JYYK+wDjJF1q99KK4JLL+egWS4nmNqdlMUgCExMZ+iZW0hGhyC3VEbsPjvaN0TBhW//VIFwBrk8sEiw==} + engines: {node: '>=6.9.0'} + + /@babel/core@7.19.3: + resolution: {integrity: sha512-WneDJxdsjEvyKtXKsaBGbDeiyOjR5vYq4HcShxnIbG0qixpoHjI3MqeZM9NDvsojNCEBItQE4juOo/bU6e72gQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@ampproject/remapping': 2.2.0 + '@babel/code-frame': 7.18.6 + '@babel/generator': 7.19.3 + '@babel/helper-compilation-targets': 7.19.3(@babel/core@7.19.3) + '@babel/helper-module-transforms': 7.19.0 + '@babel/helpers': 7.19.0 + '@babel/parser': 7.19.3 + '@babel/template': 7.18.10 + '@babel/traverse': 7.19.3 + '@babel/types': 7.19.3 + convert-source-map: 1.8.0 + debug: 4.3.4 + gensync: 1.0.0-beta.2 + json5: 2.2.1 + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + + /@babel/generator@7.19.3: + resolution: {integrity: sha512-fqVZnmp1ncvZU757UzDheKZpfPgatqY59XtW2/j/18H7u76akb8xqvjw82f+i2UKd/ksYsSick/BCLQUUtJ/qQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.19.3 + '@jridgewell/gen-mapping': 0.3.2 + jsesc: 2.5.2 + + /@babel/helper-compilation-targets@7.19.3(@babel/core@7.19.3): + resolution: {integrity: sha512-65ESqLGyGmLvgR0mst5AdW1FkNlj9rQsCKduzEoEPhBCDFGXvz2jW6bXFG6i0/MrV2s7hhXjjb2yAzcPuQlLwg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/compat-data': 7.19.3 + '@babel/core': 7.19.3 + '@babel/helper-validator-option': 7.18.6 + browserslist: 4.21.4 + semver: 6.3.0 + + /@babel/helper-environment-visitor@7.18.9: + resolution: {integrity: sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==} + engines: {node: '>=6.9.0'} + + /@babel/helper-function-name@7.19.0: + resolution: {integrity: sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.18.10 + '@babel/types': 7.19.3 + + /@babel/helper-hoist-variables@7.18.6: + resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.19.3 + + /@babel/helper-module-imports@7.18.6: + resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.19.0 + + /@babel/helper-module-transforms@7.19.0: + resolution: {integrity: sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-module-imports': 7.18.6 + '@babel/helper-simple-access': 7.18.6 + '@babel/helper-split-export-declaration': 7.18.6 + '@babel/helper-validator-identifier': 7.18.6 + '@babel/template': 7.18.10 + '@babel/traverse': 7.19.3 + '@babel/types': 7.19.3 + transitivePeerDependencies: + - supports-color + + /@babel/helper-plugin-utils@7.19.0: + resolution: {integrity: sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==} + engines: {node: '>=6.9.0'} + dev: false + + /@babel/helper-simple-access@7.18.6: + resolution: {integrity: sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.19.3 + + /@babel/helper-split-export-declaration@7.18.6: + resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.19.3 + + /@babel/helper-string-parser@7.18.10: + resolution: {integrity: sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==} + engines: {node: '>=6.9.0'} + + /@babel/helper-validator-identifier@7.18.6: + resolution: {integrity: sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==} + engines: {node: '>=6.9.0'} + + /@babel/helper-validator-identifier@7.19.1: + resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==} + engines: {node: '>=6.9.0'} + + /@babel/helper-validator-option@7.18.6: + resolution: {integrity: sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==} + engines: {node: '>=6.9.0'} + + /@babel/helpers@7.19.0: + resolution: {integrity: sha512-DRBCKGwIEdqY3+rPJgG/dKfQy9+08rHIAJx8q2p+HSWP87s2HCrQmaAMMyMll2kIXKCW0cO1RdQskx15Xakftg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.18.10 + '@babel/traverse': 7.19.3 + '@babel/types': 7.19.3 + transitivePeerDependencies: + - supports-color + + /@babel/highlight@7.18.6: + resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': 7.18.6 + chalk: 2.4.2 + js-tokens: 4.0.0 + + /@babel/parser@7.19.3: + resolution: {integrity: sha512-pJ9xOlNWHiy9+FuFP09DEAFbAn4JskgRsVcc169w2xRBC3FRGuQEwjeIMMND9L2zc0iEhO/tGv4Zq+km+hxNpQ==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.19.3 + + /@babel/plugin-syntax-jsx@7.18.6(@babel/core@7.19.3): + resolution: {integrity: sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.19.3 + '@babel/helper-plugin-utils': 7.19.0 + dev: false + + /@babel/runtime@7.19.0: + resolution: {integrity: sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.13.9 + dev: false + + /@babel/template@7.18.10: + resolution: {integrity: sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.18.6 + '@babel/parser': 7.19.3 + '@babel/types': 7.19.3 + + /@babel/traverse@7.19.3: + resolution: {integrity: sha512-qh5yf6149zhq2sgIXmwjnsvmnNQC2iw70UFjp4olxucKrWd/dvlUsBI88VSLUsnMNF7/vnOiA+nk1+yLoCqROQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.18.6 + '@babel/generator': 7.19.3 + '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-function-name': 7.19.0 + '@babel/helper-hoist-variables': 7.18.6 + '@babel/helper-split-export-declaration': 7.18.6 + '@babel/parser': 7.19.3 + '@babel/types': 7.19.3 + debug: 4.3.4 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + /@babel/types@7.19.0: + resolution: {integrity: sha512-YuGopBq3ke25BVSiS6fgF49Ul9gH1x70Bcr6bqRLjWCkcX8Hre1/5+z+IiWOIerRMSSEfGZVB9z9kyq7wVs9YA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.18.10 + '@babel/helper-validator-identifier': 7.18.6 + to-fast-properties: 2.0.0 + + /@babel/types@7.19.3: + resolution: {integrity: sha512-hGCaQzIY22DJlDh9CH7NOxgKkFjBk0Cw9xDO1Xmh2151ti7wiGfQ3LauXzL4HP1fmFlTX6XjpRETTpUcv7wQLw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.18.10 + '@babel/helper-validator-identifier': 7.19.1 + to-fast-properties: 2.0.0 + + /@emotion/babel-plugin@11.10.2(@babel/core@7.19.3): + resolution: {integrity: sha512-xNQ57njWTFVfPAc3cjfuaPdsgLp5QOSuRsj9MA6ndEhH/AzuZM86qIQzt6rq+aGBwj3n5/TkLmU5lhAfdRmogA==} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.19.3 + '@babel/helper-module-imports': 7.18.6 + '@babel/plugin-syntax-jsx': 7.18.6(@babel/core@7.19.3) + '@babel/runtime': 7.19.0 + '@emotion/hash': 0.9.0 + '@emotion/memoize': 0.8.0 + '@emotion/serialize': 1.1.0 + babel-plugin-macros: 3.1.0 + convert-source-map: 1.8.0 + escape-string-regexp: 4.0.0 + find-root: 1.1.0 + source-map: 0.5.7 + stylis: 4.0.13 + dev: false + + /@emotion/cache@11.10.3: + resolution: {integrity: sha512-Psmp/7ovAa8appWh3g51goxu/z3iVms7JXOreq136D8Bbn6dYraPnmL6mdM8GThEx9vwSn92Fz+mGSjBzN8UPQ==} + dependencies: + '@emotion/memoize': 0.8.0 + '@emotion/sheet': 1.2.0 + '@emotion/utils': 1.2.0 + '@emotion/weak-memoize': 0.3.0 + stylis: 4.0.13 + dev: false + + /@emotion/hash@0.9.0: + resolution: {integrity: sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ==} + dev: false + + /@emotion/is-prop-valid@1.2.0: + resolution: {integrity: sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==} + dependencies: + '@emotion/memoize': 0.8.0 + dev: false + + /@emotion/memoize@0.8.0: + resolution: {integrity: sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==} + dev: false + + /@emotion/react@11.10.4(@babel/core@7.19.3)(@types/react@18.0.21)(react@18.2.0): + resolution: {integrity: sha512-j0AkMpr6BL8gldJZ6XQsQ8DnS9TxEQu1R+OGmDZiWjBAJtCcbt0tS3I/YffoqHXxH6MjgI7KdMbYKw3MEiU9eA==} + peerDependencies: + '@babel/core': ^7.0.0 + '@types/react': '*' + react: '>=16.8.0' + peerDependenciesMeta: + '@babel/core': + optional: true + '@types/react': + optional: true + dependencies: + '@babel/core': 7.19.3 + '@babel/runtime': 7.19.0 + '@emotion/babel-plugin': 11.10.2(@babel/core@7.19.3) + '@emotion/cache': 11.10.3 + '@emotion/serialize': 1.1.0 + '@emotion/use-insertion-effect-with-fallbacks': 1.0.0(react@18.2.0) + '@emotion/utils': 1.2.0 + '@emotion/weak-memoize': 0.3.0 + '@types/react': 18.0.21 + hoist-non-react-statics: 3.3.2 + react: 18.2.0 + dev: false + + /@emotion/serialize@1.1.0: + resolution: {integrity: sha512-F1ZZZW51T/fx+wKbVlwsfchr5q97iW8brAnXmsskz4d0hVB4O3M/SiA3SaeH06x02lSNzkkQv+n3AX3kCXKSFA==} + dependencies: + '@emotion/hash': 0.9.0 + '@emotion/memoize': 0.8.0 + '@emotion/unitless': 0.8.0 + '@emotion/utils': 1.2.0 + csstype: 3.1.0 + dev: false + + /@emotion/server@11.10.0: + resolution: {integrity: sha512-MTvJ21JPo9aS02GdjFW4nhdwOi2tNNpMmAM/YED0pkxzjDNi5WbiTwXqaCnvLc2Lr8NFtjhT0az1vTJyLIHYcw==} + peerDependencies: + '@emotion/css': ^11.0.0-rc.0 + peerDependenciesMeta: + '@emotion/css': + optional: true + dependencies: + '@emotion/utils': 1.2.0 + html-tokenize: 2.0.1 + multipipe: 1.0.2 + through: 2.3.8 + dev: false + + /@emotion/sheet@1.2.0: + resolution: {integrity: sha512-OiTkRgpxescko+M51tZsMq7Puu/KP55wMT8BgpcXVG2hqXc0Vo0mfymJ/Uj24Hp0i083ji/o0aLddh08UEjq8w==} + dev: false + + /@emotion/styled@11.10.4(@babel/core@7.19.3)(@emotion/react@11.10.4)(@types/react@18.0.21)(react@18.2.0): + resolution: {integrity: sha512-pRl4R8Ez3UXvOPfc2bzIoV8u9P97UedgHS4FPX594ntwEuAMA114wlaHvOK24HB48uqfXiGlYIZYCxVJ1R1ttQ==} + peerDependencies: + '@babel/core': ^7.0.0 + '@emotion/react': ^11.0.0-rc.0 + '@types/react': '*' + react: '>=16.8.0' + peerDependenciesMeta: + '@babel/core': + optional: true + '@types/react': + optional: true + dependencies: + '@babel/core': 7.19.3 + '@babel/runtime': 7.19.0 + '@emotion/babel-plugin': 11.10.2(@babel/core@7.19.3) + '@emotion/is-prop-valid': 1.2.0 + '@emotion/react': 11.10.4(@babel/core@7.19.3)(@types/react@18.0.21)(react@18.2.0) + '@emotion/serialize': 1.1.0 + '@emotion/use-insertion-effect-with-fallbacks': 1.0.0(react@18.2.0) + '@emotion/utils': 1.2.0 + '@types/react': 18.0.21 + react: 18.2.0 + dev: false + + /@emotion/unitless@0.8.0: + resolution: {integrity: sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==} + dev: false + + /@emotion/use-insertion-effect-with-fallbacks@1.0.0(react@18.2.0): + resolution: {integrity: sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A==} + peerDependencies: + react: '>=16.8.0' + dependencies: + react: 18.2.0 + dev: false + + /@emotion/utils@1.2.0: + resolution: {integrity: sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw==} + dev: false + + /@emotion/weak-memoize@0.3.0: + resolution: {integrity: sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg==} + dev: false + + /@jridgewell/gen-mapping@0.1.1: + resolution: {integrity: sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/set-array': 1.1.2 + '@jridgewell/sourcemap-codec': 1.4.14 + + /@jridgewell/gen-mapping@0.3.2: + resolution: {integrity: sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/set-array': 1.1.2 + '@jridgewell/sourcemap-codec': 1.4.14 + '@jridgewell/trace-mapping': 0.3.15 + + /@jridgewell/resolve-uri@3.1.0: + resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} + engines: {node: '>=6.0.0'} + + /@jridgewell/set-array@1.1.2: + resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} + engines: {node: '>=6.0.0'} + + /@jridgewell/sourcemap-codec@1.4.14: + resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} + + /@jridgewell/trace-mapping@0.3.15: + resolution: {integrity: sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==} + dependencies: + '@jridgewell/resolve-uri': 3.1.0 + '@jridgewell/sourcemap-codec': 1.4.14 + + /@mui/base@5.0.0-alpha.100(@types/react@18.0.21)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-bSoJEKCENtmJrJDECHUe9PiqztIUACuSskyqw9ypqE7Dz3WxL3e8puFsWBkUsz+WOCjXh4B4Xljn88Ucxxv5HA==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@types/react': ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.19.0 + '@emotion/is-prop-valid': 1.2.0 + '@mui/types': 7.2.0(@types/react@18.0.21) + '@mui/utils': 5.10.6(react@18.2.0) + '@popperjs/core': 2.11.6 + '@types/react': 18.0.21 + clsx: 1.2.1 + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-is: 18.2.0 + dev: false + + /@mui/core-downloads-tracker@5.10.8: + resolution: {integrity: sha512-V5D7OInO4P9PdT/JACg7fwjbOORm3GklaMVgdGomjyxiyetgRND5CC9r35e1LK/DqHdoyDuhbFzdfrqWtpmEIw==} + dev: false + + /@mui/icons-material@5.10.6(@mui/material@5.10.8)(@types/react@18.0.21)(react@18.2.0): + resolution: {integrity: sha512-QwxdRmLA46S94B0hExPDx0td+A2unF+33bQ6Cs+lNpJKVsm1YeHwNdYXYcnpWeHeQQ07055OXl7IB2GKDd0MfA==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@mui/material': ^5.0.0 + '@types/react': ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.19.0 + '@mui/material': 5.10.8(@emotion/react@11.10.4)(@emotion/styled@11.10.4)(@types/react@18.0.21)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.0.21 + react: 18.2.0 + dev: false + + /@mui/lab@5.0.0-alpha.102(@emotion/react@11.10.4)(@emotion/styled@11.10.4)(@mui/material@5.10.8)(@types/react@18.0.21)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-hIJ82FGdll2NmEp6b2kBhIZ5j/yiOThObBoSYo7WhH+cQCLowbgdAMH45JP9/R8J2qe2lq1K/PI3bLgcGVZ+Rw==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@emotion/react': ^11.5.0 + '@emotion/styled': ^11.3.0 + '@mui/material': ^5.0.0 + '@types/react': ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@emotion/react': + optional: true + '@emotion/styled': + optional: true + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.19.0 + '@emotion/react': 11.10.4(@babel/core@7.19.3)(@types/react@18.0.21)(react@18.2.0) + '@emotion/styled': 11.10.4(@babel/core@7.19.3)(@emotion/react@11.10.4)(@types/react@18.0.21)(react@18.2.0) + '@mui/base': 5.0.0-alpha.100(@types/react@18.0.21)(react-dom@18.2.0)(react@18.2.0) + '@mui/material': 5.10.8(@emotion/react@11.10.4)(@emotion/styled@11.10.4)(@types/react@18.0.21)(react-dom@18.2.0)(react@18.2.0) + '@mui/system': 5.10.8(@emotion/react@11.10.4)(@emotion/styled@11.10.4)(@types/react@18.0.21)(react@18.2.0) + '@mui/types': 7.2.0(@types/react@18.0.21) + '@mui/utils': 5.10.6(react@18.2.0) + '@types/react': 18.0.21 + clsx: 1.2.1 + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-is: 18.2.0 + dev: false + + /@mui/material@5.10.8(@emotion/react@11.10.4)(@emotion/styled@11.10.4)(@types/react@18.0.21)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-sF/Ka0IJjGXV52zoT4xAWEqXVRjNYbIjATo9L4Q5oQC5iJpGrKJFY16uNtWWB0+vp/nayAuPGZHrxtV+t3ecdQ==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@emotion/react': ^11.5.0 + '@emotion/styled': ^11.3.0 + '@types/react': ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@emotion/react': + optional: true + '@emotion/styled': + optional: true + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.19.0 + '@emotion/react': 11.10.4(@babel/core@7.19.3)(@types/react@18.0.21)(react@18.2.0) + '@emotion/styled': 11.10.4(@babel/core@7.19.3)(@emotion/react@11.10.4)(@types/react@18.0.21)(react@18.2.0) + '@mui/base': 5.0.0-alpha.100(@types/react@18.0.21)(react-dom@18.2.0)(react@18.2.0) + '@mui/core-downloads-tracker': 5.10.8 + '@mui/system': 5.10.8(@emotion/react@11.10.4)(@emotion/styled@11.10.4)(@types/react@18.0.21)(react@18.2.0) + '@mui/types': 7.2.0(@types/react@18.0.21) + '@mui/utils': 5.10.6(react@18.2.0) + '@types/react': 18.0.21 + '@types/react-transition-group': 4.4.5 + clsx: 1.2.1 + csstype: 3.1.1 + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-is: 18.2.0 + react-transition-group: 4.4.5(react-dom@18.2.0)(react@18.2.0) + dev: false + + /@mui/private-theming@5.10.6(@types/react@18.0.21)(react@18.2.0): + resolution: {integrity: sha512-I/W0QyTLRdEx6py3lKAquKO/rNF/7j+nIOM/xCyI9kU0fcotVTcTY08mKMsS6vrzdWpi6pAkD0wP0KwWy5R5VA==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@types/react': ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.19.0 + '@mui/utils': 5.10.6(react@18.2.0) + '@types/react': 18.0.21 + prop-types: 15.8.1 + react: 18.2.0 + dev: false + + /@mui/styled-engine@5.10.8(@emotion/react@11.10.4)(@emotion/styled@11.10.4)(react@18.2.0): + resolution: {integrity: sha512-w+y8WI18EJV6zM/q41ug19cE70JTeO6sWFsQ7tgePQFpy6ToCVPh0YLrtqxUZXSoMStW5FMw0t9fHTFAqPbngw==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@emotion/react': ^11.4.1 + '@emotion/styled': ^11.3.0 + react: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@emotion/react': + optional: true + '@emotion/styled': + optional: true + dependencies: + '@babel/runtime': 7.19.0 + '@emotion/cache': 11.10.3 + '@emotion/react': 11.10.4(@babel/core@7.19.3)(@types/react@18.0.21)(react@18.2.0) + '@emotion/styled': 11.10.4(@babel/core@7.19.3)(@emotion/react@11.10.4)(@types/react@18.0.21)(react@18.2.0) + csstype: 3.1.1 + prop-types: 15.8.1 + react: 18.2.0 + dev: false + + /@mui/system@5.10.8(@emotion/react@11.10.4)(@emotion/styled@11.10.4)(@types/react@18.0.21)(react@18.2.0): + resolution: {integrity: sha512-hRQ354zcrYP/KHqK8FheICSvE9raQaUgQaV+A3oD4JETaFUCVI9Ytt+RcQYgTqx02xlCXIjl8LK1rPjTneySqw==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@emotion/react': ^11.5.0 + '@emotion/styled': ^11.3.0 + '@types/react': ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@emotion/react': + optional: true + '@emotion/styled': + optional: true + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.19.0 + '@emotion/react': 11.10.4(@babel/core@7.19.3)(@types/react@18.0.21)(react@18.2.0) + '@emotion/styled': 11.10.4(@babel/core@7.19.3)(@emotion/react@11.10.4)(@types/react@18.0.21)(react@18.2.0) + '@mui/private-theming': 5.10.6(@types/react@18.0.21)(react@18.2.0) + '@mui/styled-engine': 5.10.8(@emotion/react@11.10.4)(@emotion/styled@11.10.4)(react@18.2.0) + '@mui/types': 7.2.0(@types/react@18.0.21) + '@mui/utils': 5.10.6(react@18.2.0) + '@types/react': 18.0.21 + clsx: 1.2.1 + csstype: 3.1.1 + prop-types: 15.8.1 + react: 18.2.0 + dev: false + + /@mui/types@7.2.0(@types/react@18.0.21): + resolution: {integrity: sha512-lGXtFKe5lp3UxTBGqKI1l7G8sE2xBik8qCfrLHD5olwP/YU0/ReWoWT7Lp1//ri32dK39oPMrJN8TgbkCSbsNA==} + peerDependencies: + '@types/react': '*' + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.0.21 + dev: false + + /@mui/utils@5.10.6(react@18.2.0): + resolution: {integrity: sha512-g0Qs8xN/MW2M3fLL8197h5J2VB9U+49fLlnKKqC6zy/yus5cZwdT+Gwec+wUMxgwQoxMDn+J8oDWAn28kEOR/Q==} + engines: {node: '>=12.0.0'} + peerDependencies: + react: ^17.0.0 || ^18.0.0 + dependencies: + '@babel/runtime': 7.19.0 + '@types/prop-types': 15.7.5 + '@types/react-is': 17.0.3 + prop-types: 15.8.1 + react: 18.2.0 + react-is: 18.2.0 + dev: false + + /@next/env@12.3.1: + resolution: {integrity: sha512-9P9THmRFVKGKt9DYqeC2aKIxm8rlvkK38V1P1sRE7qyoPBIs8l9oo79QoSdPtOWfzkbDAVUqvbQGgTMsb8BtJg==} + dev: false + + /@next/swc-android-arm-eabi@12.3.1: + resolution: {integrity: sha512-i+BvKA8tB//srVPPQxIQN5lvfROcfv4OB23/L1nXznP+N/TyKL8lql3l7oo2LNhnH66zWhfoemg3Q4VJZSruzQ==} + engines: {node: '>= 10'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: false + optional: true + + /@next/swc-android-arm64@12.3.1: + resolution: {integrity: sha512-CmgU2ZNyBP0rkugOOqLnjl3+eRpXBzB/I2sjwcGZ7/Z6RcUJXK5Evz+N0ucOxqE4cZ3gkTeXtSzRrMK2mGYV8Q==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: false + optional: true + + /@next/swc-darwin-arm64@12.3.1: + resolution: {integrity: sha512-hT/EBGNcu0ITiuWDYU9ur57Oa4LybD5DOQp4f22T6zLfpoBMfBibPtR8XktXmOyFHrL/6FC2p9ojdLZhWhvBHg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@next/swc-darwin-x64@12.3.1: + resolution: {integrity: sha512-9S6EVueCVCyGf2vuiLiGEHZCJcPAxglyckTZcEwLdJwozLqN0gtS0Eq0bQlGS3dH49Py/rQYpZ3KVWZ9BUf/WA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@next/swc-freebsd-x64@12.3.1: + resolution: {integrity: sha512-qcuUQkaBZWqzM0F1N4AkAh88lLzzpfE6ImOcI1P6YeyJSsBmpBIV8o70zV+Wxpc26yV9vpzb+e5gCyxNjKJg5Q==} + engines: {node: '>= 10'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: false + optional: true + + /@next/swc-linux-arm-gnueabihf@12.3.1: + resolution: {integrity: sha512-diL9MSYrEI5nY2wc/h/DBewEDUzr/DqBjIgHJ3RUNtETAOB3spMNHvJk2XKUDjnQuluLmFMloet9tpEqU2TT9w==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@next/swc-linux-arm64-gnu@12.3.1: + resolution: {integrity: sha512-o/xB2nztoaC7jnXU3Q36vGgOolJpsGG8ETNjxM1VAPxRwM7FyGCPHOMk1XavG88QZSQf+1r+POBW0tLxQOJ9DQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@next/swc-linux-arm64-musl@12.3.1: + resolution: {integrity: sha512-2WEasRxJzgAmP43glFNhADpe8zB7kJofhEAVNbDJZANp+H4+wq+/cW1CdDi8DqjkShPEA6/ejJw+xnEyDID2jg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@next/swc-linux-x64-gnu@12.3.1: + resolution: {integrity: sha512-JWEaMyvNrXuM3dyy9Pp5cFPuSSvG82+yABqsWugjWlvfmnlnx9HOQZY23bFq3cNghy5V/t0iPb6cffzRWylgsA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@next/swc-linux-x64-musl@12.3.1: + resolution: {integrity: sha512-xoEWQQ71waWc4BZcOjmatuvPUXKTv6MbIFzpm4LFeCHsg2iwai0ILmNXf81rJR+L1Wb9ifEke2sQpZSPNz1Iyg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@next/swc-win32-arm64-msvc@12.3.1: + resolution: {integrity: sha512-hswVFYQYIeGHE2JYaBVtvqmBQ1CppplQbZJS/JgrVI3x2CurNhEkmds/yqvDONfwfbttTtH4+q9Dzf/WVl3Opw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@next/swc-win32-ia32-msvc@12.3.1: + resolution: {integrity: sha512-Kny5JBehkTbKPmqulr5i+iKntO5YMP+bVM8Hf8UAmjSMVo3wehyLVc9IZkNmcbxi+vwETnQvJaT5ynYBkJ9dWA==} + engines: {node: '>= 10'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@next/swc-win32-x64-msvc@12.3.1: + resolution: {integrity: sha512-W1ijvzzg+kPEX6LAc+50EYYSEo0FVu7dmTE+t+DM4iOLqgGHoW9uYSz9wCVdkXOEEMP9xhXfGpcSxsfDucyPkA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@popperjs/core@2.11.6: + resolution: {integrity: sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==} + dev: false + + /@swc/helpers@0.4.11: + resolution: {integrity: sha512-rEUrBSGIoSFuYxwBYtlUFMlE2CwGhmW+w9355/5oduSw8e5h2+Tj4UrAGNNgP9915++wj5vkQo0UuOBqOAq4nw==} + dependencies: + tslib: 2.4.0 + dev: false + + /@types/node@18.8.3: + resolution: {integrity: sha512-0os9vz6BpGwxGe9LOhgP/ncvYN5Tx1fNcd2TM3rD/aCGBkysb+ZWpXEocG24h6ZzOi13+VB8HndAQFezsSOw1w==} + dev: true + + /@types/parse-json@4.0.0: + resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==} + dev: false + + /@types/prop-types@15.7.5: + resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} + + /@types/react-dom@18.0.6: + resolution: {integrity: sha512-/5OFZgfIPSwy+YuIBP/FgJnQnsxhZhjjrnxudMddeblOouIodEQ75X14Rr4wGSG/bknL+Omy9iWlLo1u/9GzAA==} + dependencies: + '@types/react': 18.0.21 + dev: true + + /@types/react-is@17.0.3: + resolution: {integrity: sha512-aBTIWg1emtu95bLTLx0cpkxwGW3ueZv71nE2YFBpL8k/z5czEW8yYpOo8Dp+UUAFAtKwNaOsh/ioSeQnWlZcfw==} + dependencies: + '@types/react': 18.0.21 + dev: false + + /@types/react-transition-group@4.4.5: + resolution: {integrity: sha512-juKD/eiSM3/xZYzjuzH6ZwpP+/lejltmiS3QEzV/vmb/Q8+HfDmxu+Baga8UEMGBqV88Nbg4l2hY/K2DkyaLLA==} + dependencies: + '@types/react': 18.0.21 + dev: false + + /@types/react@18.0.21: + resolution: {integrity: sha512-7QUCOxvFgnD5Jk8ZKlUAhVcRj7GuJRjnjjiY/IUBWKgOlnvDvTMLD4RTF7NPyVmbRhNrbomZiOepg7M/2Kj1mA==} + dependencies: + '@types/prop-types': 15.7.5 + '@types/scheduler': 0.16.2 + csstype: 3.1.0 + + /@types/scheduler@0.16.2: + resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==} + + /@types/uuid@8.3.4: + resolution: {integrity: sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==} + dev: true + + /ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + dependencies: + color-convert: 1.9.3 + + /asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + dev: false + + /axios@0.27.2: + resolution: {integrity: sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==} + dependencies: + follow-redirects: 1.15.2 + form-data: 4.0.0 + transitivePeerDependencies: + - debug + dev: false + + /babel-plugin-macros@3.1.0: + resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==} + engines: {node: '>=10', npm: '>=6'} + dependencies: + '@babel/runtime': 7.19.0 + cosmiconfig: 7.0.1 + resolve: 1.22.1 + dev: false + + /browserslist@4.21.4: + resolution: {integrity: sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: 1.0.30001407 + electron-to-chromium: 1.4.255 + node-releases: 2.0.6 + update-browserslist-db: 1.0.9(browserslist@4.21.4) + + /buffer-from@0.1.2: + resolution: {integrity: sha512-RiWIenusJsmI2KcvqQABB83tLxCByE3upSP8QU3rJDMVFGPWLvPQJt/O1Su9moRWeH7d+Q2HYb68f6+v+tw2vg==} + dev: false + + /callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + dev: false + + /caniuse-lite@1.0.30001407: + resolution: {integrity: sha512-4ydV+t4P7X3zH83fQWNDX/mQEzYomossfpViCOx9zHBSMV+rIe3LFqglHHtVyvNl1FhTNxPxs3jei82iqOW04w==} + + /chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + + /clsx@1.2.1: + resolution: {integrity: sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==} + engines: {node: '>=6'} + dev: false + + /color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + dependencies: + color-name: 1.1.3 + + /color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + + /combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + dependencies: + delayed-stream: 1.0.0 + dev: false + + /convert-source-map@1.8.0: + resolution: {integrity: sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==} + dependencies: + safe-buffer: 5.1.2 + + /core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + dev: false + + /cosmiconfig@7.0.1: + resolution: {integrity: sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==} + engines: {node: '>=10'} + dependencies: + '@types/parse-json': 4.0.0 + import-fresh: 3.3.0 + parse-json: 5.2.0 + path-type: 4.0.0 + yaml: 1.10.2 + dev: false + + /csstype@3.1.0: + resolution: {integrity: sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA==} + + /csstype@3.1.1: + resolution: {integrity: sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==} + dev: false + + /debug@4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + + /delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + dev: false + + /dom-helpers@5.2.1: + resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==} + dependencies: + '@babel/runtime': 7.19.0 + csstype: 3.1.1 + dev: false + + /duplexer2@0.1.4: + resolution: {integrity: sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==} + dependencies: + readable-stream: 2.3.7 + dev: false + + /dwolla-v2@4.0.0-ts-alpha.0(form-data@4.0.0): + resolution: {integrity: sha512-D3pq/VPcy2VVZgreQvLlYV6RFhOHjdvHPSuv0C6VDNQGm1xTTmv53+XrtKUFEx7E7JPWq/Ax/5tTy1w2IMxRPw==} + peerDependencies: + form-data: ^4.0.0 + peerDependenciesMeta: + form-data: + optional: true + dependencies: + form-data: 4.0.0 + form-urlencoded: 6.1.0 + node-fetch: 2.6.7 + transitivePeerDependencies: + - encoding + dev: false + + /electron-to-chromium@1.4.255: + resolution: {integrity: sha512-H+mFNKow6gi2P5Gi2d1Fvd3TUEJlB9CF7zYaIV9T83BE3wP1xZ0mRPbNTm0KUjyd1QiVy7iKXuIcjlDtBQMiAQ==} + + /error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + dependencies: + is-arrayish: 0.2.1 + dev: false + + /escalade@3.1.1: + resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} + engines: {node: '>=6'} + + /escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + + /escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + dev: false + + /find-root@1.1.0: + resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==} + dev: false + + /follow-redirects@1.15.2: + resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + dev: false + + /form-data@4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: false + + /form-urlencoded@6.1.0: + resolution: {integrity: sha512-lc1Qd9nnEewXKoiPjIA1n38M5STbyY6krgoegsg7SsAt2b98HZKe25KaJvKFBwQaOcmh8FP7JbXVC7gocZw+XQ==} + dev: false + + /function-bind@1.1.1: + resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + dev: false + + /gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + /globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + + /has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + + /has@1.0.3: + resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} + engines: {node: '>= 0.4.0'} + dependencies: + function-bind: 1.1.1 + dev: false + + /hoist-non-react-statics@3.3.2: + resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} + dependencies: + react-is: 16.13.1 + dev: false + + /html-tokenize@2.0.1: + resolution: {integrity: sha512-QY6S+hZ0f5m1WT8WffYN+Hg+xm/w5I8XeUcAq/ZYP5wVC8xbKi4Whhru3FtrAebD5EhBW8rmFzkDI6eCAuFe2w==} + hasBin: true + dependencies: + buffer-from: 0.1.2 + inherits: 2.0.4 + minimist: 1.2.6 + readable-stream: 1.0.34 + through2: 0.4.2 + dev: false + + /import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + dev: false + + /inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + dev: false + + /is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + dev: false + + /is-core-module@2.10.0: + resolution: {integrity: sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==} + dependencies: + has: 1.0.3 + dev: false + + /isarray@0.0.1: + resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==} + dev: false + + /isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + dev: false + + /js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + /jsesc@2.5.2: + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} + engines: {node: '>=4'} + hasBin: true + + /json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + dev: false + + /json5@2.2.1: + resolution: {integrity: sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==} + engines: {node: '>=6'} + hasBin: true + + /lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + dev: false + + /loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + dependencies: + js-tokens: 4.0.0 + dev: false + + /mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + dev: false + + /mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.52.0 + dev: false + + /minimist@1.2.6: + resolution: {integrity: sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==} + dev: false + + /ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + /multipipe@1.0.2: + resolution: {integrity: sha512-6uiC9OvY71vzSGX8lZvSqscE7ft9nPupJ8fMjrCNRAUy2LREUW42UL+V/NTrogr6rFgRydUrCX4ZitfpSNkSCQ==} + dependencies: + duplexer2: 0.1.4 + object-assign: 4.1.1 + dev: false + + /nanoid@3.3.4: + resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + dev: false + + /next@12.3.1(@babel/core@7.19.3)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-l7bvmSeIwX5lp07WtIiP9u2ytZMv7jIeB8iacR28PuUEFG5j0HGAPnMqyG5kbZNBG2H7tRsrQ4HCjuMOPnANZw==} + engines: {node: '>=12.22.0'} + hasBin: true + peerDependencies: + fibers: '>= 3.1.0' + node-sass: ^6.0.0 || ^7.0.0 + react: ^17.0.2 || ^18.0.0-0 + react-dom: ^17.0.2 || ^18.0.0-0 + sass: ^1.3.0 + peerDependenciesMeta: + fibers: + optional: true + node-sass: + optional: true + sass: + optional: true + dependencies: + '@next/env': 12.3.1 + '@swc/helpers': 0.4.11 + caniuse-lite: 1.0.30001407 + postcss: 8.4.14 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + styled-jsx: 5.0.7(@babel/core@7.19.3)(react@18.2.0) + use-sync-external-store: 1.2.0(react@18.2.0) + optionalDependencies: + '@next/swc-android-arm-eabi': 12.3.1 + '@next/swc-android-arm64': 12.3.1 + '@next/swc-darwin-arm64': 12.3.1 + '@next/swc-darwin-x64': 12.3.1 + '@next/swc-freebsd-x64': 12.3.1 + '@next/swc-linux-arm-gnueabihf': 12.3.1 + '@next/swc-linux-arm64-gnu': 12.3.1 + '@next/swc-linux-arm64-musl': 12.3.1 + '@next/swc-linux-x64-gnu': 12.3.1 + '@next/swc-linux-x64-musl': 12.3.1 + '@next/swc-win32-arm64-msvc': 12.3.1 + '@next/swc-win32-ia32-msvc': 12.3.1 + '@next/swc-win32-x64-msvc': 12.3.1 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + dev: false + + /node-fetch@2.6.7: + resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + dependencies: + whatwg-url: 5.0.0 + dev: false + + /node-releases@2.0.6: + resolution: {integrity: sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==} + + /object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + dev: false + + /object-keys@0.4.0: + resolution: {integrity: sha512-ncrLw+X55z7bkl5PnUvHwFK9FcGuFYo9gtjws2XtSzL+aZ8tm830P60WJ0dSmFVaSalWieW5MD7kEdnXda9yJw==} + dev: false + + /parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + dependencies: + callsites: 3.1.0 + dev: false + + /parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + dependencies: + '@babel/code-frame': 7.18.6 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + dev: false + + /path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + dev: false + + /path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + dev: false + + /picocolors@1.0.0: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + + /postcss@8.4.14: + resolution: {integrity: sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.4 + picocolors: 1.0.0 + source-map-js: 1.0.2 + dev: false + + /process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + dev: false + + /prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + dev: false + + /react-dom@18.2.0(react@18.2.0): + resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} + peerDependencies: + react: ^18.2.0 + dependencies: + loose-envify: 1.4.0 + react: 18.2.0 + scheduler: 0.23.0 + dev: false + + /react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + dev: false + + /react-is@18.2.0: + resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} + dev: false + + /react-transition-group@4.4.5(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==} + peerDependencies: + react: '>=16.6.0' + react-dom: '>=16.6.0' + dependencies: + '@babel/runtime': 7.19.0 + dom-helpers: 5.2.1 + loose-envify: 1.4.0 + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /react@18.2.0: + resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} + engines: {node: '>=0.10.0'} + dependencies: + loose-envify: 1.4.0 + dev: false + + /readable-stream@1.0.34: + resolution: {integrity: sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==} + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 0.0.1 + string_decoder: 0.10.31 + dev: false + + /readable-stream@2.3.7: + resolution: {integrity: sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==} + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + dev: false + + /regenerator-runtime@0.13.9: + resolution: {integrity: sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==} + dev: false + + /resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + dev: false + + /resolve@1.22.1: + resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} + hasBin: true + dependencies: + is-core-module: 2.10.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: false + + /safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + /scheduler@0.23.0: + resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==} + dependencies: + loose-envify: 1.4.0 + dev: false + + /semver@6.3.0: + resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} + hasBin: true + + /source-map-js@1.0.2: + resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} + engines: {node: '>=0.10.0'} + dev: false + + /source-map@0.5.7: + resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} + engines: {node: '>=0.10.0'} + dev: false + + /string_decoder@0.10.31: + resolution: {integrity: sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==} + dev: false + + /string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + dependencies: + safe-buffer: 5.1.2 + dev: false + + /styled-jsx@5.0.7(@babel/core@7.19.3)(react@18.2.0): + resolution: {integrity: sha512-b3sUzamS086YLRuvnaDigdAewz1/EFYlHpYBP5mZovKEdQQOIIYq8lApylub3HHZ6xFjV051kkGU7cudJmrXEA==} + engines: {node: '>= 12.0.0'} + peerDependencies: + '@babel/core': '*' + babel-plugin-macros: '*' + react: '>= 16.8.0 || 17.x.x || ^18.0.0-0' + peerDependenciesMeta: + '@babel/core': + optional: true + babel-plugin-macros: + optional: true + dependencies: + '@babel/core': 7.19.3 + react: 18.2.0 + dev: false + + /stylis@4.0.13: + resolution: {integrity: sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag==} + dev: false + + /supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + dependencies: + has-flag: 3.0.0 + + /supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + dev: false + + /through2@0.4.2: + resolution: {integrity: sha512-45Llu+EwHKtAZYTPPVn3XZHBgakWMN3rokhEv5hu596XP+cNgplMg+Gj+1nmAvj+L0K7+N49zBKx5rah5u0QIQ==} + dependencies: + readable-stream: 1.0.34 + xtend: 2.1.2 + dev: false + + /through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + dev: false + + /to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + + /tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + dev: false + + /tslib@2.4.0: + resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==} + dev: false + + /update-browserslist-db@1.0.9(browserslist@4.21.4): + resolution: {integrity: sha512-/xsqn21EGVdXI3EXSum1Yckj3ZVZugqyOZQ/CxYPBD/R+ko9NSUScf8tFF4dOKY+2pvSSJA/S+5B8s4Zr4kyvg==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + dependencies: + browserslist: 4.21.4 + escalade: 3.1.1 + picocolors: 1.0.0 + + /use-sync-external-store@1.2.0(react@18.2.0): + resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + react: 18.2.0 + dev: false + + /usehooks-ts@2.9.1(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-2FAuSIGHlY+apM9FVlj8/oNhd+1y+Uwv5QNkMQz1oSfdHk4PXo1qoCw9I5M7j0vpH8CSWFJwXbVPeYDjLCx9PA==} + engines: {node: '>=16.15.0', npm: '>=8'} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + dev: false + + /uuid@9.0.0: + resolution: {integrity: sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==} + hasBin: true + dev: false + + /webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + dev: false + + /whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + dev: false + + /xtend@2.1.2: + resolution: {integrity: sha512-vMNKzr2rHP9Dp/e1NQFnLQlwlhp9L/LfvnsVdHxN1f+uggyVI3i08uD14GPvCToPkdsRfyPqIyYGmIk58V98ZQ==} + engines: {node: '>=0.4'} + dependencies: + object-keys: 0.4.0 + dev: false + + /yaml@1.10.2: + resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} + engines: {node: '>= 6'} + dev: false diff --git a/packages/flinks-token-exchange/src/createEmotionCache.ts b/packages/flinks-token-exchange/src/createEmotionCache.ts new file mode 100644 index 0000000..dbe7f98 --- /dev/null +++ b/packages/flinks-token-exchange/src/createEmotionCache.ts @@ -0,0 +1,10 @@ +import createCache from "@emotion/cache"; + +const isBrowser = typeof document !== "undefined"; + +export default function createEmotionCache() { + const insertionPoint: HTMLMetaElement | undefined = isBrowser + ? document.querySelector("meta[name='emotion-insertion-point']") ?? undefined + : undefined; + return createCache({ key: "mui-style", insertionPoint }); +} diff --git a/packages/flinks-token-exchange/src/hooks/useFlinksConnect.ts b/packages/flinks-token-exchange/src/hooks/useFlinksConnect.ts new file mode 100644 index 0000000..0ccb1e4 --- /dev/null +++ b/packages/flinks-token-exchange/src/hooks/useFlinksConnect.ts @@ -0,0 +1,30 @@ +import { useEventListener } from "usehooks-ts"; + +export interface ConnectLaunchOptions { + url: string; +} + +export interface ConnectEvent { + step: string; +} + +export interface ConnectSuccessEvent extends ConnectEvent { + loginId: string; +} + +export const useFlinksConnect = (onMessage: (event: MessageEvent) => void) => { + useEventListener("message", onMessage); + + function applyStyles() { + const style = document.createElement("style"); + style.setAttribute("type", "text/css"); + style.innerHTML = ` + @media (min-width: 768px) { + .flinksconnect { width: 100%; } + }`; + + const head = document.getElementsByTagName("head")[0]; + head.appendChild(style); + } + return { applyStyles }; +}; diff --git a/packages/flinks-token-exchange/src/hooks/useNetworkAlert.ts b/packages/flinks-token-exchange/src/hooks/useNetworkAlert.ts new file mode 100644 index 0000000..369bb3a --- /dev/null +++ b/packages/flinks-token-exchange/src/hooks/useNetworkAlert.ts @@ -0,0 +1,44 @@ +import type { AlertColor } from "@mui/material"; +import { useState } from "react"; + +export enum NetworkState { + LOADING = "LOADING", + NOT_LOADING = "NOT_LOADING" +} + +export interface MuiAlert { + message: string; + severity: AlertColor; +} + +export interface UpdateNetworkAlertOptions { + alert?: MuiAlert; + networkState: NetworkState; +} + +export const useNetworkAlert = () => { + /** + * The current alert state. Is usually shown to the user if not `undefined`. + */ + const [alert, setAlert] = useState(); + + /** + * The current network state. Is usually used to indicate if a resource is loading. + */ + const [networkState, setNetworkState] = useState(NetworkState.NOT_LOADING); + + /** + * Update the current alert by specifying both the new message (or none) and whether + * a resource has begun/finished loading. + */ + function updateNetworkAlert({ alert, networkState }: UpdateNetworkAlertOptions) { + setAlert(alert); + setNetworkState(networkState); + } + + return { + alert, + networkState, + updateNetworkAlert + }; +}; diff --git a/packages/flinks-token-exchange/src/integrations/dwolla.ts b/packages/flinks-token-exchange/src/integrations/dwolla.ts new file mode 100644 index 0000000..5255d4b --- /dev/null +++ b/packages/flinks-token-exchange/src/integrations/dwolla.ts @@ -0,0 +1,97 @@ +import { Client } from "dwolla-v2"; +import { equalsIgnoreCase } from "../utils"; +import { getEnvironmentVariable } from "./"; + +export interface CreateExchangeOptions { + customerId: string; + exchangePartnerHref: string; + authSecret: string; + accessToken: string; +} + +export interface CreateFundingSourceOptions { + customerId: string; + exchangeUrl: string; + name: string; + type: "checking" | "savings"; +} + +export interface CreateUnverifiedCustomerOptions { + firstName: string; + lastName: string; + email: string; +} + +const client = new Client({ + environment: getEnvironmentVariable("DWOLLA_ENV").toLowerCase() as "production" | "sandbox", + key: getEnvironmentVariable("DWOLLA_KEY"), + secret: getEnvironmentVariable("DWOLLA_SECRET") +}); + +/** + * Creates a customer exchange resource using the token that was retrieved from Flinks. + */ +export async function createExchange({ + customerId, + exchangePartnerHref, + authSecret, + accessToken +}: CreateExchangeOptions): Promise { + const response = await client.post(`/customers/${customerId}/exchanges`, { + _links: { + "exchange-partner": { + href: exchangePartnerHref + } + }, + token: tokenifyFlinksAuth(authSecret, accessToken) + }); + return response.headers.get("Location"); +} + +/** + * Creates a funding source for a customer using an exchange URL. + */ +export async function createFundingSource({ + customerId, + exchangeUrl, + name, + type +}: CreateFundingSourceOptions): Promise { + const response = await client.post(`/customers/${customerId}/funding-sources`, { + _links: { + exchange: { + href: exchangeUrl + } + }, + bankAccountType: type, + name + }); + return response.headers.get("Location"); +} + +/** + * Creates an unverified customer record. + */ +export async function createUnverifiedCustomer(options: CreateUnverifiedCustomerOptions): Promise { + const response = await client.post("customers", { ...options }); + return response.headers.get("Location"); +} + +/** + * Gets Flinks' exchange partner href (link) within Dwolla's systems. + */ +export async function getExchangePartnerHref(): Promise { + const response = await client.get("/exchange-partners"); + const partnersList = response.body._embedded["exchange-partners"]; + const flinksPartner = partnersList.filter((obj: { name: string }) => equalsIgnoreCase(obj.name, "Flinks"))[0]; + return flinksPartner._links.self.href; +} + +/** + * Combine Flinks AuthSecret and AccessToken in Basic Auth format and then Base64 encode. + * + * This token is used to create a Dwolla exchange. + */ +function tokenifyFlinksAuth(authSecret: string, accessToken: string): string { + return Buffer.from(`${authSecret}:${accessToken}`, 'utf-8').toString("base64"); +} diff --git a/packages/flinks-token-exchange/src/integrations/flinks.ts b/packages/flinks-token-exchange/src/integrations/flinks.ts new file mode 100644 index 0000000..5faedd8 --- /dev/null +++ b/packages/flinks-token-exchange/src/integrations/flinks.ts @@ -0,0 +1,136 @@ +import type { AxiosRequestConfig } from "axios"; +import axios from "axios"; +import { getEnvironmentVariable } from "."; + +export interface Account { + readonly Id: string; +} + +export interface GenerateRequestIdOptions { + loginId: string; + mostRecentCached?: boolean; +} + +export interface GenerateRequestIdResponse { + readonly RequestId: string; +} + +export interface GetAccountsSummaryOptions { + requestId: string; + withBalance?: boolean; +} + +export interface GetAccountsSummaryResponse { + readonly Accounts: Account | Account[]; +} + +export interface RequestAuthSecretOptions { + nameOfPartner: string; +} + +export interface RequestAuthSecretResponse { + readonly AuthSecret: string; +} + +export interface RequestAccessTokenOptions { + loginId: string; + accountId: string; +} + +export interface RequestAccessTokenResponse { + readonly AccessToken: string; +} + +const DWOLLA_ENV = getEnvironmentVariable("DWOLLA_ENV").toLowerCase() as "production" | "sandbox"; +const API_SECRET = getEnvironmentVariable("FLINKS_API_SECRET"); +const INSTANCE = getEnvironmentVariable("FLINKS_INSTANCE"); +const CUSTOMER_ID = getEnvironmentVariable("FLINKS_CUSTOMER_ID"); + +const FLINKS_BASE_URI = `https://${INSTANCE}-api.private.fin.ag/v3/${CUSTOMER_ID}`; + +const axiosRequestConfig: AxiosRequestConfig = { + headers: { + Accept: "application/json" + } +}; + +const axiosInstance = axios.create(axiosRequestConfig); + +/** + * Builds a IFrame URL that allows the user to connect their FI. + * @see {@link https://docs.flinks.com/docs/connecting-accounts-widget|Flinks Connect Widget} + */ +export function buildConnectWidget(): { url: string; isDemo: boolean } { + const useDemo = Boolean(DWOLLA_ENV === "sandbox"); + return { url: `https://${INSTANCE}-iframe.private.fin.ag/v2/?demo=${useDemo}`, isDemo: useDemo }; +} + +/** + * Generates a Flinks requestId which is used to call Flinks' accounts summary API. + * + * @see {@link https://docs.flinks.com/reference/authorize|/Authorize} + */ +export async function generateRequestId(options: GenerateRequestIdOptions): Promise { + const response = await axiosInstance.post( + `${FLINKS_BASE_URI}/BankingServices/Authorize`, + { + LoginId: options.loginId, + MostRecentCached: options.mostRecentCached ?? true + }, + { + headers: { + "Content-Type": "application/json" + } + } + ); + return { RequestId: response.data.RequestId }; +} + +/** + * Generates a Flinks requestId which is used to call Flinks' accounts summary API. + * + * @see {@link https://docs.flinks.com/reference/getaccountssummary|/GetAccountsSummary} + */ +export async function getAccountsSummary(options: GetAccountsSummaryOptions): Promise { + const response = await axiosInstance.post( + `${FLINKS_BASE_URI}/BankingServices/GetAccountsSummary`, + { + RequestId: options.requestId, + WithBalance: options.withBalance + }, + { + headers: { + "Content-Type": "application/json" + } + } + ); + return { Accounts: response.data.Accounts }; +} + +/** + * Requests an AuthSecret from Flinks that is sent to Dwolla. + * + * @see {@link https://docs.flinks.com/reference/authsecret|/AuthSecret} + */ +export async function requestAuthSecret(options: RequestAuthSecretOptions): Promise { + const response = await axiosInstance.get(`${FLINKS_BASE_URI}/partnerdata/authsecret/${options.nameOfPartner}`, { + headers: { + Authorization: `Bearer ${API_SECRET}` + } + }); + return { AuthSecret: response.data.AuthSecret }; +} + +/** + * Requests an AccessToken from Flinks that is sent to Dwolla. + * + * @see {@link https://docs.flinks.com/reference/partnerdata-client|/PartnerData} + */ +export async function requestAccessToken(options: RequestAccessTokenOptions): Promise { + const response = await axiosInstance.get(`${FLINKS_BASE_URI}/partnerdata/${options.loginId}/${options.accountId}`, { + headers: { + Authorization: `Bearer ${API_SECRET}` + } + }); + return { AccessToken: response.data.AccessToken }; +} diff --git a/packages/flinks-token-exchange/src/integrations/index.ts b/packages/flinks-token-exchange/src/integrations/index.ts new file mode 100644 index 0000000..93a9c57 --- /dev/null +++ b/packages/flinks-token-exchange/src/integrations/index.ts @@ -0,0 +1,5 @@ +import { v4 } from "uuid"; + +export const getEnvironmentVariable = (key: string): string => process.env[key] as string; + +export const newUuid = (): string => v4(); diff --git a/packages/flinks-token-exchange/src/layouts/MainLayout.tsx b/packages/flinks-token-exchange/src/layouts/MainLayout.tsx new file mode 100644 index 0000000..90962ad --- /dev/null +++ b/packages/flinks-token-exchange/src/layouts/MainLayout.tsx @@ -0,0 +1,29 @@ +import { Container, styled } from "@mui/material"; +import Head from "next/head"; +import type { ReactNode } from "react"; + +interface Props { + children?: ReactNode; + title: string; +} + +const ParentBox = styled("div", { name: "ParentBox" })(({ theme }) => ({ + alignItems: "center", + display: "flex", + flexDirection: "column", + justifyContent: "center", + marginTop: theme.spacing(4) +})); + +const MainLayout: (props: Props) => JSX.Element = ({ children, title }) => ( + <> + + {title} + + + {children} + + +); + +export default MainLayout; diff --git a/packages/flinks-token-exchange/src/pages/_app.tsx b/packages/flinks-token-exchange/src/pages/_app.tsx new file mode 100644 index 0000000..db5b72a --- /dev/null +++ b/packages/flinks-token-exchange/src/pages/_app.tsx @@ -0,0 +1,30 @@ +import type { EmotionCache } from "@emotion/cache"; +import { CacheProvider } from "@emotion/react"; +import { CssBaseline, ThemeProvider } from "@mui/material"; +import type { AppProps } from "next/app"; +import Head from "next/head"; +import createEmotionCache from "../createEmotionCache"; +import theme from "../theme"; + +interface Props extends AppProps { + emotionCache?: EmotionCache; +} + +const clientSideEmotionCache = createEmotionCache(); + +function MyApp({ Component, emotionCache = clientSideEmotionCache, pageProps }: Props) { + return ( + + + Dwolla Token Exchange Example + + + + + + + + ); +} + +export default MyApp; diff --git a/packages/flinks-token-exchange/src/pages/_document.tsx b/packages/flinks-token-exchange/src/pages/_document.tsx new file mode 100644 index 0000000..cd1d64a --- /dev/null +++ b/packages/flinks-token-exchange/src/pages/_document.tsx @@ -0,0 +1,57 @@ +import createEmotionServer from "@emotion/server/create-instance"; +import type { DocumentContext } from "next/document"; +import Document, { Head, Html, Main, NextScript } from "next/document"; +import createEmotionCache from "../createEmotionCache"; +import theme from "../theme"; + +export default class MyDocument extends Document { + static async getInitialProps(ctx: DocumentContext) { + const originalRenderPage = ctx.renderPage; + + const cache = createEmotionCache(); + const { extractCriticalToChunks } = createEmotionServer(cache); + + ctx.renderPage = () => + originalRenderPage({ + enhanceApp: (App) => + function EnhancedApp(props: any) { + return ; + } + }); + + const initialProps = await Document.getInitialProps(ctx); + const emotionStyles = extractCriticalToChunks(initialProps.html); + const emotionStyleTags = emotionStyles.styles.map((style) => ( +