Repository: auth0/nextjs-auth0
Pull request #815 (2022-09-09 15:35:51)

[SDK-3554] Next.js Middlware support
- [x] All new/changed/fixed functionality is covered by tests (or N/A)
- [x] I have added documentation for all new/changed functionality (or N/A)

### 📋 Changes

Added a new `withMiddlwareAuthRequired` helper, to protect routes using middleware.

To protect all your routes:

```js
// middleware.js
import { withMiddlewareAuthRequired } from '@auth0/nextjs-auth0/middleware';

export default withMiddlewareAuthRequired();
```

To protect specific routes:
```js
// middleware.js
import { withMiddlewareAuthRequired } from '@auth0/nextjs-auth0/middleware';

export default withMiddlewareAuthRequired();

export const config = {
  matcher: '/about/:path*',
}
```
For more info see: https://nextjs.org/docs/advanced-features/middleware#matching-paths

To run custom middleware for authenticated users:
```js
// middleware.js
import { withMiddlewareAuthRequired, getSession } from '@auth0/nextjs-auth0/middleware';

export default withMiddlewareAuthRequired(async function middleware(req) {
  const res = NextResponse.next();
  const user = await getSession(req, res);
  res.cookies.set('hl', user.language);
  return res;
});
```

### 📎 References

See https://github.com/auth0/nextjs-auth0/issues/525
https://nextjs.org/docs/advanced-features/middleware

### 🎯 Testing

Run kitchen-sink example app
Visit http://localhost:3000/profile-mw


Patch:
diff --git a/EXAMPLES.md b/EXAMPLES.md
index eda18278..ca449282 100644
--- a/EXAMPLES.md
+++ b/EXAMPLES.md
@@ -6,6 +6,7 @@
 - [Protecting a Server-Side Rendered (SSR) Page](#protecting-a-server-side-rendered-ssr-page)
 - [Protecting a Client-Side Rendered (CSR) Page](#protecting-a-client-side-rendered-csr-page)
 - [Protect an API Route](#protect-an-api-route)
+- [Protecting pages with Middleware](#protecting-pages-with-middleware)
 - [Access an External API from an API Route](#access-an-external-api-from-an-api-route)
 - [Create your own instance of the SDK](#create-your-own-instance-of-the-sdk)
 - [Add a signup handler](#add-a-signup-handler)
@@ -206,6 +207,48 @@ export default withPageAuthRequired(function Products() {
 See a running example in the kitchen-sink example app, the [protected API route](./examples/kitchen-sink-example/pages/api/shows.ts) and
 the [frontend code to access the protected API](./examples/kitchen-sink-example/pages/shows.tsx).
 
+## Protecting pages with Middleware
+
+Protect your pages with Next.js Middleware.
+
+To protect all your routes:
+
+```js
+// middleware.js
+import { withMiddlewareAuthRequired } from '@auth0/nextjs-auth0/middleware';
+
+export default withMiddlewareAuthRequired();
+```
+
+To protect specific routes:
+
+```js
+// middleware.js
+import { withMiddlewareAuthRequired } from '@auth0/nextjs-auth0/middleware';
+
+export default withMiddlewareAuthRequired();
+
+export const config = {
+  matcher: '/about/:path*'
+};
+```
+
+For more info see: https://nextjs.org/docs/advanced-features/middleware#matching-paths
+
+To run custom middleware for authenticated users:
+
+```js
+// middleware.js
+import { withMiddlewareAuthRequired, getSession } from '@auth0/nextjs-auth0/middleware';
+
+export default withMiddlewareAuthRequired(async function middleware(req) {
+  const res = NextResponse.next();
+  const user = await getSession(req, res);
+  res.cookies.set('hl', user.language);
+  return res;
+});
+```
+
 ## Access an External API from an API Route
 
 Get an Access Token by providing your API's audience and scopes. You can pass them directly to the `handlelogin` method, or use environment variables instead.
diff --git a/README.md b/README.md
index 26b07034..fbd8cf0d 100644
--- a/README.md
+++ b/README.md
@@ -183,6 +183,7 @@ For other comprehensive examples, see the [EXAMPLES.md](./EXAMPLES.md) document.
 - [handleProfile](https://auth0.github.io/nextjs-auth0/modules/handlers_profile.html)
 - [withApiAuthRequired](https://auth0.github.io/nextjs-auth0/modules/helpers_with_api_auth_required.html)
 - [withPageAuthRequired](https://auth0.github.io/nextjs-auth0/modules/helpers_with_page_auth_required.html#withpageauthrequired)
+- [withMiddlewareAuthRequired](https://auth0.github.io/nextjs-auth0/modules/helpers_with_middleware_auth_required.html)
 - [getSession](https://auth0.github.io/nextjs-auth0/modules/session_get_session.html)
 - [updateUser](https://auth0.github.io/nextjs-auth0/modules/session_update_user.html)
 - [getAccessToken](https://auth0.github.io/nextjs-auth0/modules/session_get_access_token.html)
diff --git a/examples/basic-example/next.config.js b/examples/basic-example/next.config.js
index b5449e13..4f336cb7 100644
--- a/examples/basic-example/next.config.js
+++ b/examples/basic-example/next.config.js
@@ -1,4 +1,3 @@
 module.exports = {
-  poweredByHeader: false,
-  target: 'serverless'
+  poweredByHeader: false
 };
diff --git a/examples/kitchen-sink-example/middleware.ts b/examples/kitchen-sink-example/middleware.ts
new file mode 100644
index 00000000..71300945
--- /dev/null
+++ b/examples/kitchen-sink-example/middleware.ts
@@ -0,0 +1,7 @@
+import { withMiddlewareAuthRequired } from '@auth0/nextjs-auth0/middleware';
+
+export default withMiddlewareAuthRequired();
+
+export const config = {
+  matcher: '/profile-mw'
+};
diff --git a/examples/kitchen-sink-example/next.config.js b/examples/kitchen-sink-example/next.config.js
index b5449e13..4f336cb7 100644
--- a/examples/kitchen-sink-example/next.config.js
+++ b/examples/kitchen-sink-example/next.config.js
@@ -1,4 +1,3 @@
 module.exports = {
-  poweredByHeader: false,
-  target: 'serverless'
+  poweredByHeader: false
 };
diff --git a/examples/kitchen-sink-example/pages/profile-mw.tsx b/examples/kitchen-sink-example/pages/profile-mw.tsx
new file mode 100644
index 00000000..2d6aaed5
--- /dev/null
+++ b/examples/kitchen-sink-example/pages/profile-mw.tsx
@@ -0,0 +1,18 @@
+import React from 'react';
+import { useUser } from '@auth0/nextjs-auth0';
+
+import Layout from '../components/layout';
+
+export default function Profile() {
+  const { user, isLoading } = useUser();
+  if (isLoading) {
+    return <p>Loading...</p>;
+  }
+  return (
+    <Layout>
+      <h1>Profile</h1>
+      <h4>Profile</h4>
+      <pre data-testid="profile">{JSON.stringify(user, null, 2)}</pre>
+    </Layout>
+  );
+}
diff --git a/examples/kitchen-sink-example/pages/profile-ssr.tsx b/examples/kitchen-sink-example/pages/profile-ssr.tsx
index 545b4a3a..872a44f5 100644
--- a/examples/kitchen-sink-example/pages/profile-ssr.tsx
+++ b/examples/kitchen-sink-example/pages/profile-ssr.tsx
@@ -9,11 +9,8 @@ export default function Profile({ user }: ProfileProps): React.ReactElement {
   return (
     <Layout>
       <h1>Profile</h1>
-
-      <div>
-        <h4>Profile (server rendered)</h4>
-        <pre data-testid="profile">{JSON.stringify(user, null, 2)}</pre>
-      </div>
+      <h4>Profile (server rendered)</h4>
+      <pre data-testid="profile">{JSON.stringify(user, null, 2)}</pre>
     </Layout>
   );
 }
diff --git a/middleware.d.ts b/middleware.d.ts
new file mode 100644
index 00000000..f0d69b8f
--- /dev/null
+++ b/middleware.d.ts
@@ -0,0 +1,5 @@
+import type { WithMiddlewareAuthRequired, GetSession, InitAuth0 } from './dist/middleware';
+
+export declare const initAuth0: InitAuth0;
+export declare const getSession: GetSession;
+export declare const withMiddlewareAuthRequired: WithMiddlewareAuthRequired;
diff --git a/middleware.js b/middleware.js
new file mode 100644
index 00000000..e5396c61
--- /dev/null
+++ b/middleware.js
@@ -0,0 +1,1 @@
+module.exports = require('./dist/middleware');
diff --git a/package-lock.json b/package-lock.json
index f8cf29f5..9ac23f69 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -20,6 +20,7 @@
         "url-join": "^4.0.1"
       },
       "devDependencies": {
+        "@edge-runtime/jest-environment": "^1.1.0-beta.31",
         "@testing-library/jest-dom": "^5.11.9",
         "@testing-library/react": "^11.2.3",
         "@testing-library/react-hooks": "^5.0.3",
@@ -51,7 +52,7 @@
         "eslint-plugin-react": "^7.22.0",
         "eslint-plugin-react-hooks": "^4.2.0",
         "jest": "^27.2.0",
-        "next": "^12.1.6",
+        "next": "^12.2.5",
         "nock": "^13.0.5",
         "oidc-provider": "^7.6.0",
         "on-headers": "^1.0.2",
@@ -293,9 +294,9 @@
       }
     },
     "node_modules/@babel/helper-plugin-utils": {
-      "version": "7.17.12",
-      "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.17.12.tgz",
-      "integrity": "sha512-JDkf04mqtN3y4iAbO1hv9U2ARpPyPL1zqyWs/2WG1pgSq9llHFjStX5jdxb84himgJm+8Ng+x0oiWF/nw/XQKA==",
+      "version": "7.19.0",
+      "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz",
+      "integrity": "sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==",
       "dev": true,
       "engines": {
         "node": ">=6.9.0"
@@ -341,9 +342,9 @@
       }
     },
     "node_modules/@babel/helper-validator-identifier": {
-      "version": "7.16.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz",
-      "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==",
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz",
+      "integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==",
       "dev": true,
       "engines": {
         "node": ">=6.9.0"
@@ -373,12 +374,12 @@
       }
     },
     "node_modules/@babel/highlight": {
-      "version": "7.17.12",
-      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.17.12.tgz",
-      "integrity": "sha512-7yykMVF3hfZY2jsHZEEgLc+3x4o1O+fYyULu11GynEUQNwB6lua+IIQn1FiJxNucd5UlyJryrwsOh8PL9Sn8Qg==",
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz",
+      "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==",
       "dev": true,
       "dependencies": {
-        "@babel/helper-validator-identifier": "^7.16.7",
+        "@babel/helper-validator-identifier": "^7.18.6",
         "chalk": "^2.0.0",
         "js-tokens": "^4.0.0"
       },
@@ -608,12 +609,12 @@
       }
     },
     "node_modules/@babel/plugin-syntax-typescript": {
-      "version": "7.17.12",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.17.12.tgz",
-      "integrity": "sha512-TYY0SXFiO31YXtNg3HtFwNJHjLsAyIIhAhNWkQ5whPPS7HWUFlg9z0Ta4qAQNjQbP1wsSt/oKkmZ/4/WWdMUpw==",
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz",
+      "integrity": "sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA==",
       "dev": true,
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.17.12"
+        "@babel/helper-plugin-utils": "^7.18.6"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -792,6 +793,94 @@
         "ms": "^2.1.1"
       }
     },
+    "node_modules/@edge-runtime/jest-environment": {
+      "version": "1.1.0-beta.31",
+      "resolved": "https://registry.npmjs.org/@edge-runtime/jest-environment/-/jest-environment-1.1.0-beta.31.tgz",
+      "integrity": "sha512-a65LVlCMkwkMxg8RjhEY5o3OZFHzMnLZcGqL234h3HO7Ri1Vriorj330BcPSh2GUt4zFqTS/3+XmWE6ueJwAZg==",
+      "dev": true,
+      "dependencies": {
+        "@edge-runtime/vm": "^1.1.0-beta.31",
+        "@jest/environment": "28.1.3",
+        "@jest/fake-timers": "28.1.3",
+        "@jest/types": "28.1.3",
+        "jest-mock": "28.1.3",
+        "jest-util": "28.1.3"
+      }
+    },
+    "node_modules/@edge-runtime/jest-environment/node_modules/@jest/types": {
+      "version": "28.1.3",
+      "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz",
+      "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==",
+      "dev": true,
+      "dependencies": {
+        "@jest/schemas": "^28.1.3",
+        "@types/istanbul-lib-coverage": "^2.0.0",
+        "@types/istanbul-reports": "^3.0.0",
+        "@types/node": "*",
+        "@types/yargs": "^17.0.8",
+        "chalk": "^4.0.0"
+      },
+      "engines": {
+        "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
+      }
+    },
+    "node_modules/@edge-runtime/jest-environment/node_modules/@types/yargs": {
+      "version": "17.0.12",
+      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.12.tgz",
+      "integrity": "sha512-Nz4MPhecOFArtm81gFQvQqdV7XYCrWKx5uUt6GNHredFHn1i2mtWqXTON7EPXMtNi1qjtjEM/VCHDhcHsAMLXQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/yargs-parser": "*"
+      }
+    },
+    "node_modules/@edge-runtime/jest-environment/node_modules/chalk": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^4.1.0",
+        "supports-color": "^7.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/chalk?sponsor=1"
+      }
+    },
+    "node_modules/@edge-runtime/jest-environment/node_modules/jest-util": {
+      "version": "28.1.3",
+      "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz",
+      "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==",
+      "dev": true,
+      "dependencies": {
+        "@jest/types": "^28.1.3",
+        "@types/node": "*",
+        "chalk": "^4.0.0",
+        "ci-info": "^3.2.0",
+        "graceful-fs": "^4.2.9",
+        "picomatch": "^2.2.3"
+      },
+      "engines": {
+        "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
+      }
+    },
+    "node_modules/@edge-runtime/primitives": {
+      "version": "1.1.0-beta.31",
+      "resolved": "https://registry.npmjs.org/@edge-runtime/primitives/-/primitives-1.1.0-beta.31.tgz",
+      "integrity": "sha512-OO1x32aJoxgME1k77RVxVNsazs5NY/SNwYEN8ptlZ6DKUXn0eesXftDsmlypX/OU0ZeJc61/xNVUuoeyDGJDVA==",
+      "dev": true
+    },
+    "node_modules/@edge-runtime/vm": {
+      "version": "1.1.0-beta.31",
+      "resolved": "https://registry.npmjs.org/@edge-runtime/vm/-/vm-1.1.0-beta.31.tgz",
+      "integrity": "sha512-D3JW32u7LSTt0KbphGWx2F41jId7BY8H0Awr25PTRFWroqohfWo1C2huOh7/Yyn4qeyJOVEuxWeTzvbSkTyyTg==",
+      "dev": true,
+      "dependencies": {
+        "@edge-runtime/primitives": "^1.1.0-beta.31"
+      }
+    },
     "node_modules/@eslint/eslintrc": {
       "version": "0.4.3",
       "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz",
@@ -966,6 +1055,18 @@
         "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
       }
     },
+    "node_modules/@jest/console/node_modules/@babel/code-frame": {
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
+      "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
+      "dev": true,
+      "dependencies": {
+        "@babel/highlight": "^7.18.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
     "node_modules/@jest/console/node_modules/@jest/types": {
       "version": "27.5.1",
       "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz",
@@ -1007,6 +1108,58 @@
         "url": "https://github.com/chalk/chalk?sponsor=1"
       }
     },
+    "node_modules/@jest/console/node_modules/jest-message-util": {
+      "version": "27.5.1",
+      "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz",
+      "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==",
+      "dev": true,
+      "dependencies": {
+        "@babel/code-frame": "^7.12.13",
+        "@jest/types": "^27.5.1",
+        "@types/stack-utils": "^2.0.0",
+        "chalk": "^4.0.0",
+        "graceful-fs": "^4.2.9",
+        "micromatch": "^4.0.4",
+        "pretty-format": "^27.5.1",
+        "slash": "^3.0.0",
+        "stack-utils": "^2.0.3"
+      },
+      "engines": {
+        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+      }
+    },
+    "node_modules/@jest/console/node_modules/pretty-format": {
+      "version": "27.5.1",
+      "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
+      "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
+      "dev": true,
+      "dependencies": {
+        "ansi-regex": "^5.0.1",
+        "ansi-styles": "^5.0.0",
+        "react-is": "^17.0.1"
+      },
+      "engines": {
+        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+      }
+    },
+    "node_modules/@jest/console/node_modules/pretty-format/node_modules/ansi-styles": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+      "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+      }
+    },
+    "node_modules/@jest/console/node_modules/react-is": {
+      "version": "17.0.2",
+      "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+      "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+      "dev": true
+    },
     "node_modules/@jest/core": {
       "version": "27.5.1",
       "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.5.1.tgz",
@@ -1054,6 +1207,18 @@
         }
       }
     },
+    "node_modules/@jest/core/node_modules/@babel/code-frame": {
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
+      "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
+      "dev": true,
+      "dependencies": {
+        "@babel/highlight": "^7.18.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
     "node_modules/@jest/core/node_modules/@jest/types": {
       "version": "27.5.1",
       "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz",
@@ -1095,41 +1260,94 @@
         "url": "https://github.com/chalk/chalk?sponsor=1"
       }
     },
-    "node_modules/@jest/environment": {
+    "node_modules/@jest/core/node_modules/jest-message-util": {
       "version": "27.5.1",
-      "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz",
-      "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==",
+      "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz",
+      "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==",
       "dev": true,
       "dependencies": {
-        "@jest/fake-timers": "^27.5.1",
+        "@babel/code-frame": "^7.12.13",
         "@jest/types": "^27.5.1",
-        "@types/node": "*",
-        "jest-mock": "^27.5.1"
+        "@types/stack-utils": "^2.0.0",
+        "chalk": "^4.0.0",
+        "graceful-fs": "^4.2.9",
+        "micromatch": "^4.0.4",
+        "pretty-format": "^27.5.1",
+        "slash": "^3.0.0",
+        "stack-utils": "^2.0.3"
       },
       "engines": {
         "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
       }
     },
-    "node_modules/@jest/environment/node_modules/@jest/types": {
+    "node_modules/@jest/core/node_modules/pretty-format": {
       "version": "27.5.1",
-      "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz",
-      "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==",
+      "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
+      "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
       "dev": true,
       "dependencies": {
+        "ansi-regex": "^5.0.1",
+        "ansi-styles": "^5.0.0",
+        "react-is": "^17.0.1"
+      },
+      "engines": {
+        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+      }
+    },
+    "node_modules/@jest/core/node_modules/pretty-format/node_modules/ansi-styles": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+      "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+      }
+    },
+    "node_modules/@jest/core/node_modules/react-is": {
+      "version": "17.0.2",
+      "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+      "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+      "dev": true
+    },
+    "node_modules/@jest/environment": {
+      "version": "28.1.3",
+      "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz",
+      "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==",
+      "dev": true,
+      "dependencies": {
+        "@jest/fake-timers": "^28.1.3",
+        "@jest/types": "^28.1.3",
+        "@types/node": "*",
+        "jest-mock": "^28.1.3"
+      },
+      "engines": {
+        "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
+      }
+    },
+    "node_modules/@jest/environment/node_modules/@jest/types": {
+      "version": "28.1.3",
+      "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz",
+      "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==",
+      "dev": true,
+      "dependencies": {
+        "@jest/schemas": "^28.1.3",
         "@types/istanbul-lib-coverage": "^2.0.0",
         "@types/istanbul-reports": "^3.0.0",
         "@types/node": "*",
-        "@types/yargs": "^16.0.0",
+        "@types/yargs": "^17.0.8",
         "chalk": "^4.0.0"
       },
       "engines": {
-        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+        "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
       }
     },
     "node_modules/@jest/environment/node_modules/@types/yargs": {
-      "version": "16.0.4",
-      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
-      "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+      "version": "17.0.12",
+      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.12.tgz",
+      "integrity": "sha512-Nz4MPhecOFArtm81gFQvQqdV7XYCrWKx5uUt6GNHredFHn1i2mtWqXTON7EPXMtNi1qjtjEM/VCHDhcHsAMLXQ==",
       "dev": true,
       "dependencies": {
         "@types/yargs-parser": "*"
@@ -1152,42 +1370,43 @@
       }
     },
     "node_modules/@jest/fake-timers": {
-      "version": "27.5.1",
-      "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz",
-      "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==",
+      "version": "28.1.3",
+      "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz",
+      "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==",
       "dev": true,
       "dependencies": {
-        "@jest/types": "^27.5.1",
-        "@sinonjs/fake-timers": "^8.0.1",
+        "@jest/types": "^28.1.3",
+        "@sinonjs/fake-timers": "^9.1.2",
         "@types/node": "*",
-        "jest-message-util": "^27.5.1",
-        "jest-mock": "^27.5.1",
-        "jest-util": "^27.5.1"
+        "jest-message-util": "^28.1.3",
+        "jest-mock": "^28.1.3",
+        "jest-util": "^28.1.3"
       },
       "engines": {
-        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+        "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
       }
     },
     "node_modules/@jest/fake-timers/node_modules/@jest/types": {
-      "version": "27.5.1",
-      "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz",
-      "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==",
+      "version": "28.1.3",
+      "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz",
+      "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==",
       "dev": true,
       "dependencies": {
+        "@jest/schemas": "^28.1.3",
         "@types/istanbul-lib-coverage": "^2.0.0",
         "@types/istanbul-reports": "^3.0.0",
         "@types/node": "*",
-        "@types/yargs": "^16.0.0",
+        "@types/yargs": "^17.0.8",
         "chalk": "^4.0.0"
       },
       "engines": {
-        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+        "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
       }
     },
     "node_modules/@jest/fake-timers/node_modules/@types/yargs": {
-      "version": "16.0.4",
-      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
-      "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+      "version": "17.0.12",
+      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.12.tgz",
+      "integrity": "sha512-Nz4MPhecOFArtm81gFQvQqdV7XYCrWKx5uUt6GNHredFHn1i2mtWqXTON7EPXMtNi1qjtjEM/VCHDhcHsAMLXQ==",
       "dev": true,
       "dependencies": {
         "@types/yargs-parser": "*"
@@ -1209,6 +1428,23 @@
         "url": "https://github.com/chalk/chalk?sponsor=1"
       }
     },
+    "node_modules/@jest/fake-timers/node_modules/jest-util": {
+      "version": "28.1.3",
+      "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz",
+      "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==",
+      "dev": true,
+      "dependencies": {
+        "@jest/types": "^28.1.3",
+        "@types/node": "*",
+        "chalk": "^4.0.0",
+        "ci-info": "^3.2.0",
+        "graceful-fs": "^4.2.9",
+        "picomatch": "^2.2.3"
+      },
+      "engines": {
+        "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
+      }
+    },
     "node_modules/@jest/globals": {
       "version": "27.5.1",
       "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.5.1.tgz",
@@ -1223,6 +1459,50 @@
         "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
       }
     },
+    "node_modules/@jest/globals/node_modules/@babel/code-frame": {
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
+      "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
+      "dev": true,
+      "dependencies": {
+        "@babel/highlight": "^7.18.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@jest/globals/node_modules/@jest/environment": {
+      "version": "27.5.1",
+      "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz",
+      "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==",
+      "dev": true,
+      "dependencies": {
+        "@jest/fake-timers": "^27.5.1",
+        "@jest/types": "^27.5.1",
+        "@types/node": "*",
+        "jest-mock": "^27.5.1"
+      },
+      "engines": {
+        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+      }
+    },
+    "node_modules/@jest/globals/node_modules/@jest/fake-timers": {
+      "version": "27.5.1",
+      "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz",
+      "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==",
+      "dev": true,
+      "dependencies": {
+        "@jest/types": "^27.5.1",
+        "@sinonjs/fake-timers": "^8.0.1",
+        "@types/node": "*",
+        "jest-message-util": "^27.5.1",
+        "jest-mock": "^27.5.1",
+        "jest-util": "^27.5.1"
+      },
+      "engines": {
+        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+      }
+    },
     "node_modules/@jest/globals/node_modules/@jest/types": {
       "version": "27.5.1",
       "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz",
@@ -1239,6 +1519,15 @@
         "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
       }
     },
+    "node_modules/@jest/globals/node_modules/@sinonjs/fake-timers": {
+      "version": "8.1.0",
+      "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz",
+      "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==",
+      "dev": true,
+      "dependencies": {
+        "@sinonjs/commons": "^1.7.0"
+      }
+    },
     "node_modules/@jest/globals/node_modules/@types/yargs": {
       "version": "16.0.4",
       "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
@@ -1264,6 +1553,71 @@
         "url": "https://github.com/chalk/chalk?sponsor=1"
       }
     },
+    "node_modules/@jest/globals/node_modules/jest-message-util": {
+      "version": "27.5.1",
+      "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz",
+      "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==",
+      "dev": true,
+      "dependencies": {
+        "@babel/code-frame": "^7.12.13",
+        "@jest/types": "^27.5.1",
+        "@types/stack-utils": "^2.0.0",
+        "chalk": "^4.0.0",
+        "graceful-fs": "^4.2.9",
+        "micromatch": "^4.0.4",
+        "pretty-format": "^27.5.1",
+        "slash": "^3.0.0",
+        "stack-utils": "^2.0.3"
+      },
+      "engines": {
+        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+      }
+    },
+    "node_modules/@jest/globals/node_modules/jest-mock": {
+      "version": "27.5.1",
+      "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz",
+      "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==",
+      "dev": true,
+      "dependencies": {
+        "@jest/types": "^27.5.1",
+        "@types/node": "*"
+      },
+      "engines": {
+        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+      }
+    },
+    "node_modules/@jest/globals/node_modules/pretty-format": {
+      "version": "27.5.1",
+      "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
+      "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
+      "dev": true,
+      "dependencies": {
+        "ansi-regex": "^5.0.1",
+        "ansi-styles": "^5.0.0",
+        "react-is": "^17.0.1"
+      },
+      "engines": {
+        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+      }
+    },
+    "node_modules/@jest/globals/node_modules/pretty-format/node_modules/ansi-styles": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+      "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+      }
+    },
+    "node_modules/@jest/globals/node_modules/react-is": {
+      "version": "17.0.2",
+      "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+      "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+      "dev": true
+    },
     "node_modules/@jest/reporters": {
       "version": "27.5.1",
       "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.5.1.tgz",
@@ -1349,6 +1703,18 @@
         "url": "https://github.com/chalk/chalk?sponsor=1"
       }
     },
+    "node_modules/@jest/schemas": {
+      "version": "28.1.3",
+      "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz",
+      "integrity": "sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==",
+      "dev": true,
+      "dependencies": {
+        "@sinclair/typebox": "^0.24.1"
+      },
+      "engines": {
+        "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
+      }
+    },
     "node_modules/@jest/source-map": {
       "version": "27.5.1",
       "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz",
@@ -1546,15 +1912,15 @@
       }
     },
     "node_modules/@next/env": {
-      "version": "12.2.3",
-      "resolved": "https://registry.npmjs.org/@next/env/-/env-12.2.3.tgz",
-      "integrity": "sha512-2lWKP5Xcvnor70NaaROZXBvU8z9mFReePCG8NhZw6NyNGnPvC+8s+Cre/63LAB1LKzWw/e9bZJnQUg0gYFRb2Q==",
+      "version": "12.2.5",
+      "resolved": "https://registry.npmjs.org/@next/env/-/env-12.2.5.tgz",
+      "integrity": "sha512-vLPLV3cpPGjUPT3PjgRj7e3nio9t6USkuew3JE/jMeon/9Mvp1WyR18v3iwnCuX7eUAm1HmAbJHHLAbcu/EJcw==",
       "dev": true
     },
     "node_modules/@next/swc-android-arm-eabi": {
-      "version": "12.2.3",
-      "resolved": "https://registry.npmjs.org/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-12.2.3.tgz",
-      "integrity": "sha512-JxmCW9XB5PYnkGE67BdnBTdqW0SW6oMCiPMHLdjeRi4T3U4JJKJGnjQld99+6TPOfPWigtw3W7Cijp5gc+vJ/w==",
+      "version": "12.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-12.2.5.tgz",
+      "integrity": "sha512-cPWClKxGhgn2dLWnspW+7psl3MoLQUcNqJqOHk2BhNcou9ARDtC0IjQkKe5qcn9qg7I7U83Gp1yh2aesZfZJMA==",
       "cpu": [
         "arm"
       ],
@@ -1568,9 +1934,9 @@
       }
     },
     "node_modules/@next/swc-android-arm64": {
-      "version": "12.2.3",
-      "resolved": "https://registry.npmjs.org/@next/swc-android-arm64/-/swc-android-arm64-12.2.3.tgz",
-      "integrity": "sha512-3l4zXpWnzy0fqoedsFRxzMy/eGlMMqn6IwPEuBmtEQ4h7srmQFHyT+Bk+eVHb0o1RQ7/TloAa+mu8JX5tz/5tA==",
+      "version": "12.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-android-arm64/-/swc-android-arm64-12.2.5.tgz",
+      "integrity": "sha512-vMj0efliXmC5b7p+wfcQCX0AfU8IypjkzT64GiKJD9PgiA3IILNiGJr1fw2lyUDHkjeWx/5HMlMEpLnTsQslwg==",
       "cpu": [
         "arm64"
       ],
@@ -1584,9 +1950,9 @@
       }
     },
     "node_modules/@next/swc-darwin-arm64": {
-      "version": "12.2.3",
-      "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-12.2.3.tgz",
-      "integrity": "sha512-eutDO/RH6pf7+8zHo3i2GKLhF0qaMtxWpY8k3Oa1k+CyrcJ0IxwkfH/x3f75jTMeCrThn6Uu8j3WeZOxvhto1Q==",
+      "version": "12.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-12.2.5.tgz",
+      "integrity": "sha512-VOPWbO5EFr6snla/WcxUKtvzGVShfs302TEMOtzYyWni6f9zuOetijJvVh9CCTzInnXAZMtHyNhefijA4HMYLg==",
       "cpu": [
         "arm64"
       ],
@@ -1600,9 +1966,9 @@
       }
     },
     "node_modules/@next/swc-darwin-x64": {
-      "version": "12.2.3",
-      "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-12.2.3.tgz",
-      "integrity": "sha512-lve+lnTiddXbcT3Lh2ujOFywQSEycTYQhuf6j6JrPu9oLQGS01kjIqqSj3/KMmSoppEnXo3BxkgYu+g2+ecHkA==",
+      "version": "12.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-12.2.5.tgz",
+      "integrity": "sha512-5o8bTCgAmtYOgauO/Xd27vW52G2/m3i5PX7MUYePquxXAnX73AAtqA3WgPXBRitEB60plSKZgOTkcpqrsh546A==",
       "cpu": [
         "x64"
       ],
@@ -1616,9 +1982,9 @@
       }
     },
     "node_modules/@next/swc-freebsd-x64": {
-      "version": "12.2.3",
-      "resolved": "https://registry.npmjs.org/@next/swc-freebsd-x64/-/swc-freebsd-x64-12.2.3.tgz",
-      "integrity": "sha512-V4bZU1qBFkULTPW53phY8ypioh3EERzHu9YKAasm9RxU4dj+8c/4s60y+kbFkFEEpIUgEU6yNuYZRR4lHHbUGA==",
+      "version": "12.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-freebsd-x64/-/swc-freebsd-x64-12.2.5.tgz",
+      "integrity": "sha512-yYUbyup1JnznMtEBRkK4LT56N0lfK5qNTzr6/DEyDw5TbFVwnuy2hhLBzwCBkScFVjpFdfiC6SQAX3FrAZzuuw==",
       "cpu": [
         "x64"
       ],
@@ -1632,9 +1998,9 @@
       }
     },
     "node_modules/@next/swc-linux-arm-gnueabihf": {
-      "version": "12.2.3",
-      "resolved": "https://registry.npmjs.org/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-12.2.3.tgz",
-      "integrity": "sha512-MWxS/i+XSEKdQE0ZmdYkPPrWKBi4JwMVaXdOW9J/T/sZJsHsLlSC9ErBcNolKAJEVka+tnw9oPRyRCKOj+q0sw==",
+      "version": "12.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-12.2.5.tgz",
+      "integrity": "sha512-2ZE2/G921Acks7UopJZVMgKLdm4vN4U0yuzvAMJ6KBavPzqESA2yHJlm85TV/K9gIjKhSk5BVtauIUntFRP8cg==",
       "cpu": [
         "arm"
       ],
@@ -1648,9 +2014,9 @@
       }
     },
     "node_modules/@next/swc-linux-arm64-gnu": {
-      "version": "12.2.3",
-      "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-12.2.3.tgz",
-      "integrity": "sha512-ikXkqAmvEcWTzIQFDdmrUHLWzdDAF5s2pVsSpQn9rk/gK1i9webH1GRQd2bSM7JLuPBZSaYrNGvDTyHZdSEYlg==",
+      "version": "12.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-12.2.5.tgz",
+      "integrity": "sha512-/I6+PWVlz2wkTdWqhlSYYJ1pWWgUVva6SgX353oqTh8njNQp1SdFQuWDqk8LnM6ulheVfSsgkDzxrDaAQZnzjQ==",
       "cpu": [
         "arm64"
       ],
@@ -1664,9 +2030,9 @@
       }
     },
     "node_modules/@next/swc-linux-arm64-musl": {
-      "version": "12.2.3",
-      "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-12.2.3.tgz",
-      "integrity": "sha512-wE45gGFkeLLLnCoveKaBrdpYkkypl3qwNF2YhnfvfVK7etuu1O679LwClhCWinDVBr+KOkmyHok00Z+0uI1ycg==",
+      "version": "12.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-12.2.5.tgz",
+      "integrity": "sha512-LPQRelfX6asXyVr59p5sTpx5l+0yh2Vjp/R8Wi4X9pnqcayqT4CUJLiHqCvZuLin3IsFdisJL0rKHMoaZLRfmg==",
       "cpu": [
         "arm64"
       ],
@@ -1680,9 +2046,9 @@
       }
     },
     "node_modules/@next/swc-linux-x64-gnu": {
-      "version": "12.2.3",
-      "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-12.2.3.tgz",
-      "integrity": "sha512-MbFI6413VSXiREzHwYD8YAJLTknBaC+bmjXgdHEEdloeOuBFQGE3NWn3izOCTy8kV+s98VDQO8au7EKKs+bW0g==",
+      "version": "12.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-12.2.5.tgz",
+      "integrity": "sha512-0szyAo8jMCClkjNK0hknjhmAngUppoRekW6OAezbEYwHXN/VNtsXbfzgYOqjKWxEx3OoAzrT3jLwAF0HdX2MEw==",
       "cpu": [
         "x64"
       ],
@@ -1696,9 +2062,9 @@
       }
     },
     "node_modules/@next/swc-linux-x64-musl": {
-      "version": "12.2.3",
-      "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-12.2.3.tgz",
-      "integrity": "sha512-jMBD0Va6fInbPih/dNySlNY2RpjkK6MXS+UGVEvuTswl1MZr+iahvurmshwGKpjaRwVU4DSFMD8+gfWxsTFs1Q==",
+      "version": "12.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-12.2.5.tgz",
+      "integrity": "sha512-zg/Y6oBar1yVnW6Il1I/08/2ukWtOG6s3acdJdEyIdsCzyQi4RLxbbhkD/EGQyhqBvd3QrC6ZXQEXighQUAZ0g==",
       "cpu": [
         "x64"
       ],
@@ -1712,9 +2078,9 @@
       }
     },
     "node_modules/@next/swc-win32-arm64-msvc": {
-      "version": "12.2.3",
-      "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-12.2.3.tgz",
-      "integrity": "sha512-Cq8ToPdc0jQP2C7pjChYctAsEe7+lO/B826ZCK5xFzobuHPiCyJ2Mzx/nEQwCY4SpYkeJQtCbwlCz5iyGW5zGg==",
+      "version": "12.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-12.2.5.tgz",
+      "integrity": "sha512-3/90DRNSqeeSRMMEhj4gHHQlLhhKg5SCCoYfE3kBjGpE63EfnblYUqsszGGZ9ekpKL/R4/SGB40iCQr8tR5Jiw==",
       "cpu": [
         "arm64"
       ],
@@ -1728,9 +2094,9 @@
       }
     },
     "node_modules/@next/swc-win32-ia32-msvc": {
-      "version": "12.2.3",
-      "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-12.2.3.tgz",
-      "integrity": "sha512-BtFq4c8IpeB0sDhJMHJFgm86rPkOvmYI8k3De8Y2kgNVWSeLQ0Q929PWf7e+GqcX1015ei/gEB41ZH8Iw49NzA==",
+      "version": "12.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-12.2.5.tgz",
+      "integrity": "sha512-hGLc0ZRAwnaPL4ulwpp4D2RxmkHQLuI8CFOEEHdzZpS63/hMVzv81g8jzYA0UXbb9pus/iTc3VRbVbAM03SRrw==",
       "cpu": [
         "ia32"
       ],
@@ -1744,9 +2110,9 @@
       }
     },
     "node_modules/@next/swc-win32-x64-msvc": {
-      "version": "12.2.3",
-      "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-12.2.3.tgz",
-      "integrity": "sha512-huSNb98KSG77Kl96CoPgCwom28aamuUsPpRmn/4s9L0RNbbHVSkp9E6HA4yOAykZCEuWcdNsRLbVVuAbt8rtIw==",
+      "version": "12.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-12.2.5.tgz",
+      "integrity": "sha512-7h5/ahY7NeaO2xygqVrSG/Y8Vs4cdjxIjowTZ5W6CKoTKn7tmnuxlUc2h74x06FKmbhAd9agOjr/AOKyxYYm9Q==",
       "cpu": [
         "x64"
       ],
@@ -1828,6 +2194,12 @@
       "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz",
       "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ=="
     },
+    "node_modules/@sinclair/typebox": {
+      "version": "0.24.38",
+      "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.38.tgz",
+      "integrity": "sha512-IbYB6vdhLFmzGEyXXEdFAJKyq7S4/RsivkgxNzs/LzwYuUJHmeNQ0cHkjG/Yqm6VgUzzZDLMZAf0XgeeaZAocA==",
+      "dev": true
+    },
     "node_modules/@sindresorhus/is": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.0.0.tgz",
@@ -1849,9 +2221,9 @@
       }
     },
     "node_modules/@sinonjs/fake-timers": {
-      "version": "8.1.0",
-      "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz",
-      "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==",
+      "version": "9.1.2",
+      "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz",
+      "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==",
       "dev": true,
       "dependencies": {
         "@sinonjs/commons": "^1.7.0"
@@ -2057,9 +2429,9 @@
       }
     },
     "node_modules/@types/babel__traverse": {
-      "version": "7.14.2",
-      "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz",
-      "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==",
+      "version": "7.18.1",
+      "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.1.tgz",
+      "integrity": "sha512-FSdLaZh2UxaMuLp9lixWaHq/golWTRWOnRsAXzDTDSDOQLuZb1nsdCt6pJSPWSEQt2eFZ2YVk3oYhn+1kLMeMA==",
       "dev": true,
       "dependencies": {
         "@babel/types": "^7.3.0"
@@ -2320,9 +2692,9 @@
       }
     },
     "node_modules/@types/prettier": {
-      "version": "2.6.3",
-      "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.3.tgz",
-      "integrity": "sha512-ymZk3LEC/fsut+/Q5qejp6R9O1rMxz3XaRHDV6kX8MrGAhOSPqVARbDi+EZvInBpw+BnCX3TD240byVkOfQsHg==",
+      "version": "2.7.0",
+      "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.0.tgz",
+      "integrity": "sha512-RI1L7N4JnW5gQw2spvL7Sllfuf1SaHdrZpCHiBlCXjIlufi1SMNnbu2teze3/QE67Fg2tBlH7W+mi4hVNk4p0A==",
       "dev": true
     },
     "node_modules/@types/prop-types": {
@@ -4773,9 +5145,9 @@
       }
     },
     "node_modules/decimal.js": {
-      "version": "10.3.1",
-      "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz",
-      "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==",
+      "version": "10.4.0",
+      "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.0.tgz",
+      "integrity": "sha512-Nv6ENEzyPQ6AItkGwLE2PGKinZZ9g59vSh2BeH6NqPu0OTKZ5ruJsVqh/orbAnqXc9pBbgXAIrc2EyaCj8NpGg==",
       "dev": true
     },
     "node_modules/decode-uri-component": {
@@ -5278,7 +5650,7 @@
     "node_modules/escodegen/node_modules/type-check": {
       "version": "0.3.2",
       "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
-      "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
+      "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==",
       "dev": true,
       "dependencies": {
         "prelude-ls": "~1.1.2"
@@ -5858,6 +6230,18 @@
         "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
       }
     },
+    "node_modules/expect/node_modules/@babel/code-frame": {
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
+      "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
+      "dev": true,
+      "dependencies": {
+        "@babel/highlight": "^7.18.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
     "node_modules/expect/node_modules/@jest/types": {
       "version": "27.5.1",
       "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz",
@@ -5899,6 +6283,58 @@
         "url": "https://github.com/chalk/chalk?sponsor=1"
       }
     },
+    "node_modules/expect/node_modules/jest-message-util": {
+      "version": "27.5.1",
+      "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz",
+      "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==",
+      "dev": true,
+      "dependencies": {
+        "@babel/code-frame": "^7.12.13",
+        "@jest/types": "^27.5.1",
+        "@types/stack-utils": "^2.0.0",
+        "chalk": "^4.0.0",
+        "graceful-fs": "^4.2.9",
+        "micromatch": "^4.0.4",
+        "pretty-format": "^27.5.1",
+        "slash": "^3.0.0",
+        "stack-utils": "^2.0.3"
+      },
+      "engines": {
+        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+      }
+    },
+    "node_modules/expect/node_modules/pretty-format": {
+      "version": "27.5.1",
+      "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
+      "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
+      "dev": true,
+      "dependencies": {
+        "ansi-regex": "^5.0.1",
+        "ansi-styles": "^5.0.0",
+        "react-is": "^17.0.1"
+      },
+      "engines": {
+        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+      }
+    },
+    "node_modules/expect/node_modules/pretty-format/node_modules/ansi-styles": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+      "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+      }
+    },
+    "node_modules/expect/node_modules/react-is": {
+      "version": "17.0.2",
+      "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+      "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+      "dev": true
+    },
     "node_modules/extend": {
       "version": "3.0.2",
       "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
@@ -7316,9 +7752,9 @@
       }
     },
     "node_modules/istanbul-reports": {
-      "version": "3.1.4",
-      "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.4.tgz",
-      "integrity": "sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw==",
+      "version": "3.1.5",
+      "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz",
+      "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==",
       "dev": true,
       "dependencies": {
         "html-escaper": "^2.0.0",
@@ -7516,6 +7952,50 @@
         "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
       }
     },
+    "node_modules/jest-circus/node_modules/@babel/code-frame": {
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
+      "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
+      "dev": true,
+      "dependencies": {
+        "@babel/highlight": "^7.18.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/jest-circus/node_modules/@jest/environment": {
+      "version": "27.5.1",
+      "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz",
+      "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==",
+      "dev": true,
+      "dependencies": {
+        "@jest/fake-timers": "^27.5.1",
+        "@jest/types": "^27.5.1",
+        "@types/node": "*",
+        "jest-mock": "^27.5.1"
+      },
+      "engines": {
+        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+      }
+    },
+    "node_modules/jest-circus/node_modules/@jest/fake-timers": {
+      "version": "27.5.1",
+      "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz",
+      "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==",
+      "dev": true,
+      "dependencies": {
+        "@jest/types": "^27.5.1",
+        "@sinonjs/fake-timers": "^8.0.1",
+        "@types/node": "*",
+        "jest-message-util": "^27.5.1",
+        "jest-mock": "^27.5.1",
+        "jest-util": "^27.5.1"
+      },
+      "engines": {
+        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+      }
+    },
     "node_modules/jest-circus/node_modules/@jest/types": {
       "version": "27.5.1",
       "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz",
@@ -7532,6 +8012,15 @@
         "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
       }
     },
+    "node_modules/jest-circus/node_modules/@sinonjs/fake-timers": {
+      "version": "8.1.0",
+      "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz",
+      "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==",
+      "dev": true,
+      "dependencies": {
+        "@sinonjs/commons": "^1.7.0"
+      }
+    },
     "node_modules/jest-circus/node_modules/@types/yargs": {
       "version": "16.0.4",
       "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
@@ -7557,6 +8046,39 @@
         "url": "https://github.com/chalk/chalk?sponsor=1"
       }
     },
+    "node_modules/jest-circus/node_modules/jest-message-util": {
+      "version": "27.5.1",
+      "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz",
+      "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==",
+      "dev": true,
+      "dependencies": {
+        "@babel/code-frame": "^7.12.13",
+        "@jest/types": "^27.5.1",
+        "@types/stack-utils": "^2.0.0",
+        "chalk": "^4.0.0",
+        "graceful-fs": "^4.2.9",
+        "micromatch": "^4.0.4",
+        "pretty-format": "^27.5.1",
+        "slash": "^3.0.0",
+        "stack-utils": "^2.0.3"
+      },
+      "engines": {
+        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+      }
+    },
+    "node_modules/jest-circus/node_modules/jest-mock": {
+      "version": "27.5.1",
+      "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz",
+      "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==",
+      "dev": true,
+      "dependencies": {
+        "@jest/types": "^27.5.1",
+        "@types/node": "*"
+      },
+      "engines": {
+        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+      }
+    },
     "node_modules/jest-circus/node_modules/pretty-format": {
       "version": "27.5.1",
       "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
@@ -7962,6 +8484,50 @@
         "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
       }
     },
+    "node_modules/jest-environment-jsdom/node_modules/@babel/code-frame": {
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
+      "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
+      "dev": true,
+      "dependencies": {
+        "@babel/highlight": "^7.18.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/jest-environment-jsdom/node_modules/@jest/environment": {
+      "version": "27.5.1",
+      "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz",
+      "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==",
+      "dev": true,
+      "dependencies": {
+        "@jest/fake-timers": "^27.5.1",
+        "@jest/types": "^27.5.1",
+        "@types/node": "*",
+        "jest-mock": "^27.5.1"
+      },
+      "engines": {
+        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+      }
+    },
+    "node_modules/jest-environment-jsdom/node_modules/@jest/fake-timers": {
+      "version": "27.5.1",
+      "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz",
+      "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==",
+      "dev": true,
+      "dependencies": {
+        "@jest/types": "^27.5.1",
+        "@sinonjs/fake-timers": "^8.0.1",
+        "@types/node": "*",
+        "jest-message-util": "^27.5.1",
+        "jest-mock": "^27.5.1",
+        "jest-util": "^27.5.1"
+      },
+      "engines": {
+        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+      }
+    },
     "node_modules/jest-environment-jsdom/node_modules/@jest/types": {
       "version": "27.5.1",
       "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz",
@@ -7978,6 +8544,15 @@
         "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
       }
     },
+    "node_modules/jest-environment-jsdom/node_modules/@sinonjs/fake-timers": {
+      "version": "8.1.0",
+      "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz",
+      "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==",
+      "dev": true,
+      "dependencies": {
+        "@sinonjs/commons": "^1.7.0"
+      }
+    },
     "node_modules/jest-environment-jsdom/node_modules/@types/yargs": {
       "version": "16.0.4",
       "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
@@ -8003,6 +8578,71 @@
         "url": "https://github.com/chalk/chalk?sponsor=1"
       }
     },
+    "node_modules/jest-environment-jsdom/node_modules/jest-message-util": {
+      "version": "27.5.1",
+      "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz",
+      "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==",
+      "dev": true,
+      "dependencies": {
+        "@babel/code-frame": "^7.12.13",
+        "@jest/types": "^27.5.1",
+        "@types/stack-utils": "^2.0.0",
+        "chalk": "^4.0.0",
+        "graceful-fs": "^4.2.9",
+        "micromatch": "^4.0.4",
+        "pretty-format": "^27.5.1",
+        "slash": "^3.0.0",
+        "stack-utils": "^2.0.3"
+      },
+      "engines": {
+        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+      }
+    },
+    "node_modules/jest-environment-jsdom/node_modules/jest-mock": {
+      "version": "27.5.1",
+      "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz",
+      "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==",
+      "dev": true,
+      "dependencies": {
+        "@jest/types": "^27.5.1",
+        "@types/node": "*"
+      },
+      "engines": {
+        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+      }
+    },
+    "node_modules/jest-environment-jsdom/node_modules/pretty-format": {
+      "version": "27.5.1",
+      "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
+      "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
+      "dev": true,
+      "dependencies": {
+        "ansi-regex": "^5.0.1",
+        "ansi-styles": "^5.0.0",
+        "react-is": "^17.0.1"
+      },
+      "engines": {
+        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+      }
+    },
+    "node_modules/jest-environment-jsdom/node_modules/pretty-format/node_modules/ansi-styles": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+      "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+      }
+    },
+    "node_modules/jest-environment-jsdom/node_modules/react-is": {
+      "version": "17.0.2",
+      "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+      "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+      "dev": true
+    },
     "node_modules/jest-environment-node": {
       "version": "27.5.1",
       "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.5.1.tgz",
@@ -8020,47 +8660,165 @@
         "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
       }
     },
-    "node_modules/jest-environment-node/node_modules/@jest/types": {
+    "node_modules/jest-environment-node/node_modules/@babel/code-frame": {
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
+      "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
+      "dev": true,
+      "dependencies": {
+        "@babel/highlight": "^7.18.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/jest-environment-node/node_modules/@jest/environment": {
+      "version": "27.5.1",
+      "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz",
+      "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==",
+      "dev": true,
+      "dependencies": {
+        "@jest/fake-timers": "^27.5.1",
+        "@jest/types": "^27.5.1",
+        "@types/node": "*",
+        "jest-mock": "^27.5.1"
+      },
+      "engines": {
+        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+      }
+    },
+    "node_modules/jest-environment-node/node_modules/@jest/fake-timers": {
+      "version": "27.5.1",
+      "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz",
+      "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==",
+      "dev": true,
+      "dependencies": {
+        "@jest/types": "^27.5.1",
+        "@sinonjs/fake-timers": "^8.0.1",
+        "@types/node": "*",
+        "jest-message-util": "^27.5.1",
+        "jest-mock": "^27.5.1",
+        "jest-util": "^27.5.1"
+      },
+      "engines": {
+        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+      }
+    },
+    "node_modules/jest-environment-node/node_modules/@jest/types": {
+      "version": "27.5.1",
+      "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz",
+      "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==",
+      "dev": true,
+      "dependencies": {
+        "@types/istanbul-lib-coverage": "^2.0.0",
+        "@types/istanbul-reports": "^3.0.0",
+        "@types/node": "*",
+        "@types/yargs": "^16.0.0",
+        "chalk": "^4.0.0"
+      },
+      "engines": {
+        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+      }
+    },
+    "node_modules/jest-environment-node/node_modules/@sinonjs/fake-timers": {
+      "version": "8.1.0",
+      "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz",
+      "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==",
+      "dev": true,
+      "dependencies": {
+        "@sinonjs/commons": "^1.7.0"
+      }
+    },
+    "node_modules/jest-environment-node/node_modules/@types/yargs": {
+      "version": "16.0.4",
+      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+      "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+      "dev": true,
+      "dependencies": {
+        "@types/yargs-parser": "*"
+      }
+    },
+    "node_modules/jest-environment-node/node_modules/chalk": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^4.1.0",
+        "supports-color": "^7.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/chalk?sponsor=1"
+      }
+    },
+    "node_modules/jest-environment-node/node_modules/jest-message-util": {
+      "version": "27.5.1",
+      "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz",
+      "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==",
+      "dev": true,
+      "dependencies": {
+        "@babel/code-frame": "^7.12.13",
+        "@jest/types": "^27.5.1",
+        "@types/stack-utils": "^2.0.0",
+        "chalk": "^4.0.0",
+        "graceful-fs": "^4.2.9",
+        "micromatch": "^4.0.4",
+        "pretty-format": "^27.5.1",
+        "slash": "^3.0.0",
+        "stack-utils": "^2.0.3"
+      },
+      "engines": {
+        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+      }
+    },
+    "node_modules/jest-environment-node/node_modules/jest-mock": {
+      "version": "27.5.1",
+      "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz",
+      "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==",
+      "dev": true,
+      "dependencies": {
+        "@jest/types": "^27.5.1",
+        "@types/node": "*"
+      },
+      "engines": {
+        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+      }
+    },
+    "node_modules/jest-environment-node/node_modules/pretty-format": {
       "version": "27.5.1",
-      "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz",
-      "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==",
+      "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
+      "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
       "dev": true,
       "dependencies": {
-        "@types/istanbul-lib-coverage": "^2.0.0",
-        "@types/istanbul-reports": "^3.0.0",
-        "@types/node": "*",
-        "@types/yargs": "^16.0.0",
-        "chalk": "^4.0.0"
+        "ansi-regex": "^5.0.1",
+        "ansi-styles": "^5.0.0",
+        "react-is": "^17.0.1"
       },
       "engines": {
         "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
       }
     },
-    "node_modules/jest-environment-node/node_modules/@types/yargs": {
-      "version": "16.0.4",
-      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
-      "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
-      "dev": true,
-      "dependencies": {
-        "@types/yargs-parser": "*"
-      }
-    },
-    "node_modules/jest-environment-node/node_modules/chalk": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
-      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+    "node_modules/jest-environment-node/node_modules/pretty-format/node_modules/ansi-styles": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+      "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
       "dev": true,
-      "dependencies": {
-        "ansi-styles": "^4.1.0",
-        "supports-color": "^7.1.0"
-      },
       "engines": {
         "node": ">=10"
       },
       "funding": {
-        "url": "https://github.com/chalk/chalk?sponsor=1"
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
       }
     },
+    "node_modules/jest-environment-node/node_modules/react-is": {
+      "version": "17.0.2",
+      "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+      "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+      "dev": true
+    },
     "node_modules/jest-get-type": {
       "version": "27.5.1",
       "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz",
@@ -8165,6 +8923,50 @@
         "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
       }
     },
+    "node_modules/jest-jasmine2/node_modules/@babel/code-frame": {
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
+      "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
+      "dev": true,
+      "dependencies": {
+        "@babel/highlight": "^7.18.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/jest-jasmine2/node_modules/@jest/environment": {
+      "version": "27.5.1",
+      "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz",
+      "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==",
+      "dev": true,
+      "dependencies": {
+        "@jest/fake-timers": "^27.5.1",
+        "@jest/types": "^27.5.1",
+        "@types/node": "*",
+        "jest-mock": "^27.5.1"
+      },
+      "engines": {
+        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+      }
+    },
+    "node_modules/jest-jasmine2/node_modules/@jest/fake-timers": {
+      "version": "27.5.1",
+      "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz",
+      "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==",
+      "dev": true,
+      "dependencies": {
+        "@jest/types": "^27.5.1",
+        "@sinonjs/fake-timers": "^8.0.1",
+        "@types/node": "*",
+        "jest-message-util": "^27.5.1",
+        "jest-mock": "^27.5.1",
+        "jest-util": "^27.5.1"
+      },
+      "engines": {
+        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+      }
+    },
     "node_modules/jest-jasmine2/node_modules/@jest/types": {
       "version": "27.5.1",
       "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz",
@@ -8181,6 +8983,15 @@
         "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
       }
     },
+    "node_modules/jest-jasmine2/node_modules/@sinonjs/fake-timers": {
+      "version": "8.1.0",
+      "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz",
+      "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==",
+      "dev": true,
+      "dependencies": {
+        "@sinonjs/commons": "^1.7.0"
+      }
+    },
     "node_modules/jest-jasmine2/node_modules/@types/yargs": {
       "version": "16.0.4",
       "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
@@ -8206,6 +9017,39 @@
         "url": "https://github.com/chalk/chalk?sponsor=1"
       }
     },
+    "node_modules/jest-jasmine2/node_modules/jest-message-util": {
+      "version": "27.5.1",
+      "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz",
+      "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==",
+      "dev": true,
+      "dependencies": {
+        "@babel/code-frame": "^7.12.13",
+        "@jest/types": "^27.5.1",
+        "@types/stack-utils": "^2.0.0",
+        "chalk": "^4.0.0",
+        "graceful-fs": "^4.2.9",
+        "micromatch": "^4.0.4",
+        "pretty-format": "^27.5.1",
+        "slash": "^3.0.0",
+        "stack-utils": "^2.0.3"
+      },
+      "engines": {
+        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+      }
+    },
+    "node_modules/jest-jasmine2/node_modules/jest-mock": {
+      "version": "27.5.1",
+      "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz",
+      "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==",
+      "dev": true,
+      "dependencies": {
+        "@jest/types": "^27.5.1",
+        "@types/node": "*"
+      },
+      "engines": {
+        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+      }
+    },
     "node_modules/jest-jasmine2/node_modules/pretty-format": {
       "version": "27.5.1",
       "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
@@ -8347,57 +9191,58 @@
       "dev": true
     },
     "node_modules/jest-message-util": {
-      "version": "27.5.1",
-      "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz",
-      "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==",
+      "version": "28.1.3",
+      "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz",
+      "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==",
       "dev": true,
       "dependencies": {
         "@babel/code-frame": "^7.12.13",
-        "@jest/types": "^27.5.1",
+        "@jest/types": "^28.1.3",
         "@types/stack-utils": "^2.0.0",
         "chalk": "^4.0.0",
         "graceful-fs": "^4.2.9",
         "micromatch": "^4.0.4",
-        "pretty-format": "^27.5.1",
+        "pretty-format": "^28.1.3",
         "slash": "^3.0.0",
         "stack-utils": "^2.0.3"
       },
       "engines": {
-        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+        "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
       }
     },
     "node_modules/jest-message-util/node_modules/@babel/code-frame": {
-      "version": "7.16.7",
-      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz",
-      "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==",
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
+      "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
       "dev": true,
       "dependencies": {
-        "@babel/highlight": "^7.16.7"
+        "@babel/highlight": "^7.18.6"
       },
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/jest-message-util/node_modules/@jest/types": {
-      "version": "27.5.1",
-      "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz",
-      "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==",
+      "version": "28.1.3",
+      "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz",
+      "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==",
       "dev": true,
       "dependencies": {
+        "@jest/schemas": "^28.1.3",
         "@types/istanbul-lib-coverage": "^2.0.0",
         "@types/istanbul-reports": "^3.0.0",
         "@types/node": "*",
-        "@types/yargs": "^16.0.0",
+        "@types/yargs": "^17.0.8",
         "chalk": "^4.0.0"
       },
       "engines": {
-        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+        "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
       }
     },
     "node_modules/jest-message-util/node_modules/@types/yargs": {
-      "version": "16.0.4",
-      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
-      "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+      "version": "17.0.12",
+      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.12.tgz",
+      "integrity": "sha512-Nz4MPhecOFArtm81gFQvQqdV7XYCrWKx5uUt6GNHredFHn1i2mtWqXTON7EPXMtNi1qjtjEM/VCHDhcHsAMLXQ==",
       "dev": true,
       "dependencies": {
         "@types/yargs-parser": "*"
@@ -8420,17 +9265,18 @@
       }
     },
     "node_modules/jest-message-util/node_modules/pretty-format": {
-      "version": "27.5.1",
-      "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
-      "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
+      "version": "28.1.3",
+      "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz",
+      "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==",
       "dev": true,
       "dependencies": {
+        "@jest/schemas": "^28.1.3",
         "ansi-regex": "^5.0.1",
         "ansi-styles": "^5.0.0",
-        "react-is": "^17.0.1"
+        "react-is": "^18.0.0"
       },
       "engines": {
-        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+        "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
       }
     },
     "node_modules/jest-message-util/node_modules/pretty-format/node_modules/ansi-styles": {
@@ -8446,44 +9292,45 @@
       }
     },
     "node_modules/jest-message-util/node_modules/react-is": {
-      "version": "17.0.2",
-      "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
-      "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+      "version": "18.2.0",
+      "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+      "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
       "dev": true
     },
     "node_modules/jest-mock": {
-      "version": "27.5.1",
-      "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz",
-      "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==",
+      "version": "28.1.3",
+      "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz",
+      "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==",
       "dev": true,
       "dependencies": {
-        "@jest/types": "^27.5.1",
+        "@jest/types": "^28.1.3",
         "@types/node": "*"
       },
       "engines": {
-        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+        "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
       }
     },
     "node_modules/jest-mock/node_modules/@jest/types": {
-      "version": "27.5.1",
-      "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz",
-      "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==",
+      "version": "28.1.3",
+      "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz",
+      "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==",
       "dev": true,
       "dependencies": {
+        "@jest/schemas": "^28.1.3",
         "@types/istanbul-lib-coverage": "^2.0.0",
         "@types/istanbul-reports": "^3.0.0",
         "@types/node": "*",
-        "@types/yargs": "^16.0.0",
+        "@types/yargs": "^17.0.8",
         "chalk": "^4.0.0"
       },
       "engines": {
-        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+        "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
       }
     },
     "node_modules/jest-mock/node_modules/@types/yargs": {
-      "version": "16.0.4",
-      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
-      "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+      "version": "17.0.12",
+      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.12.tgz",
+      "integrity": "sha512-Nz4MPhecOFArtm81gFQvQqdV7XYCrWKx5uUt6GNHredFHn1i2mtWqXTON7EPXMtNi1qjtjEM/VCHDhcHsAMLXQ==",
       "dev": true,
       "dependencies": {
         "@types/yargs-parser": "*"
@@ -8680,6 +9527,50 @@
         "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
       }
     },
+    "node_modules/jest-runner/node_modules/@babel/code-frame": {
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
+      "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
+      "dev": true,
+      "dependencies": {
+        "@babel/highlight": "^7.18.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/jest-runner/node_modules/@jest/environment": {
+      "version": "27.5.1",
+      "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz",
+      "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==",
+      "dev": true,
+      "dependencies": {
+        "@jest/fake-timers": "^27.5.1",
+        "@jest/types": "^27.5.1",
+        "@types/node": "*",
+        "jest-mock": "^27.5.1"
+      },
+      "engines": {
+        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+      }
+    },
+    "node_modules/jest-runner/node_modules/@jest/fake-timers": {
+      "version": "27.5.1",
+      "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz",
+      "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==",
+      "dev": true,
+      "dependencies": {
+        "@jest/types": "^27.5.1",
+        "@sinonjs/fake-timers": "^8.0.1",
+        "@types/node": "*",
+        "jest-message-util": "^27.5.1",
+        "jest-mock": "^27.5.1",
+        "jest-util": "^27.5.1"
+      },
+      "engines": {
+        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+      }
+    },
     "node_modules/jest-runner/node_modules/@jest/types": {
       "version": "27.5.1",
       "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz",
@@ -8696,6 +9587,15 @@
         "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
       }
     },
+    "node_modules/jest-runner/node_modules/@sinonjs/fake-timers": {
+      "version": "8.1.0",
+      "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz",
+      "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==",
+      "dev": true,
+      "dependencies": {
+        "@sinonjs/commons": "^1.7.0"
+      }
+    },
     "node_modules/jest-runner/node_modules/@types/yargs": {
       "version": "16.0.4",
       "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
@@ -8710,17 +9610,82 @@
       "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
       "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
       "dev": true,
-      "dependencies": {
-        "ansi-styles": "^4.1.0",
-        "supports-color": "^7.1.0"
-      },
+      "dependencies": {
+        "ansi-styles": "^4.1.0",
+        "supports-color": "^7.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/chalk?sponsor=1"
+      }
+    },
+    "node_modules/jest-runner/node_modules/jest-message-util": {
+      "version": "27.5.1",
+      "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz",
+      "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==",
+      "dev": true,
+      "dependencies": {
+        "@babel/code-frame": "^7.12.13",
+        "@jest/types": "^27.5.1",
+        "@types/stack-utils": "^2.0.0",
+        "chalk": "^4.0.0",
+        "graceful-fs": "^4.2.9",
+        "micromatch": "^4.0.4",
+        "pretty-format": "^27.5.1",
+        "slash": "^3.0.0",
+        "stack-utils": "^2.0.3"
+      },
+      "engines": {
+        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+      }
+    },
+    "node_modules/jest-runner/node_modules/jest-mock": {
+      "version": "27.5.1",
+      "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz",
+      "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==",
+      "dev": true,
+      "dependencies": {
+        "@jest/types": "^27.5.1",
+        "@types/node": "*"
+      },
+      "engines": {
+        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+      }
+    },
+    "node_modules/jest-runner/node_modules/pretty-format": {
+      "version": "27.5.1",
+      "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
+      "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
+      "dev": true,
+      "dependencies": {
+        "ansi-regex": "^5.0.1",
+        "ansi-styles": "^5.0.0",
+        "react-is": "^17.0.1"
+      },
+      "engines": {
+        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+      }
+    },
+    "node_modules/jest-runner/node_modules/pretty-format/node_modules/ansi-styles": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+      "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+      "dev": true,
       "engines": {
         "node": ">=10"
       },
       "funding": {
-        "url": "https://github.com/chalk/chalk?sponsor=1"
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
       }
     },
+    "node_modules/jest-runner/node_modules/react-is": {
+      "version": "17.0.2",
+      "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+      "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+      "dev": true
+    },
     "node_modules/jest-runtime": {
       "version": "27.5.1",
       "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.5.1.tgz",
@@ -8754,6 +9719,50 @@
         "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
       }
     },
+    "node_modules/jest-runtime/node_modules/@babel/code-frame": {
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
+      "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
+      "dev": true,
+      "dependencies": {
+        "@babel/highlight": "^7.18.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/jest-runtime/node_modules/@jest/environment": {
+      "version": "27.5.1",
+      "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz",
+      "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==",
+      "dev": true,
+      "dependencies": {
+        "@jest/fake-timers": "^27.5.1",
+        "@jest/types": "^27.5.1",
+        "@types/node": "*",
+        "jest-mock": "^27.5.1"
+      },
+      "engines": {
+        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+      }
+    },
+    "node_modules/jest-runtime/node_modules/@jest/fake-timers": {
+      "version": "27.5.1",
+      "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz",
+      "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==",
+      "dev": true,
+      "dependencies": {
+        "@jest/types": "^27.5.1",
+        "@sinonjs/fake-timers": "^8.0.1",
+        "@types/node": "*",
+        "jest-message-util": "^27.5.1",
+        "jest-mock": "^27.5.1",
+        "jest-util": "^27.5.1"
+      },
+      "engines": {
+        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+      }
+    },
     "node_modules/jest-runtime/node_modules/@jest/types": {
       "version": "27.5.1",
       "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz",
@@ -8770,6 +9779,15 @@
         "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
       }
     },
+    "node_modules/jest-runtime/node_modules/@sinonjs/fake-timers": {
+      "version": "8.1.0",
+      "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz",
+      "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==",
+      "dev": true,
+      "dependencies": {
+        "@sinonjs/commons": "^1.7.0"
+      }
+    },
     "node_modules/jest-runtime/node_modules/@types/yargs": {
       "version": "16.0.4",
       "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
@@ -8839,6 +9857,71 @@
         "node": ">=10.17.0"
       }
     },
+    "node_modules/jest-runtime/node_modules/jest-message-util": {
+      "version": "27.5.1",
+      "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz",
+      "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==",
+      "dev": true,
+      "dependencies": {
+        "@babel/code-frame": "^7.12.13",
+        "@jest/types": "^27.5.1",
+        "@types/stack-utils": "^2.0.0",
+        "chalk": "^4.0.0",
+        "graceful-fs": "^4.2.9",
+        "micromatch": "^4.0.4",
+        "pretty-format": "^27.5.1",
+        "slash": "^3.0.0",
+        "stack-utils": "^2.0.3"
+      },
+      "engines": {
+        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+      }
+    },
+    "node_modules/jest-runtime/node_modules/jest-mock": {
+      "version": "27.5.1",
+      "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz",
+      "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==",
+      "dev": true,
+      "dependencies": {
+        "@jest/types": "^27.5.1",
+        "@types/node": "*"
+      },
+      "engines": {
+        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+      }
+    },
+    "node_modules/jest-runtime/node_modules/pretty-format": {
+      "version": "27.5.1",
+      "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
+      "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
+      "dev": true,
+      "dependencies": {
+        "ansi-regex": "^5.0.1",
+        "ansi-styles": "^5.0.0",
+        "react-is": "^17.0.1"
+      },
+      "engines": {
+        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+      }
+    },
+    "node_modules/jest-runtime/node_modules/pretty-format/node_modules/ansi-styles": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+      "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+      }
+    },
+    "node_modules/jest-runtime/node_modules/react-is": {
+      "version": "17.0.2",
+      "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+      "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+      "dev": true
+    },
     "node_modules/jest-runtime/node_modules/strip-bom": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
@@ -8894,6 +9977,18 @@
         "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
       }
     },
+    "node_modules/jest-snapshot/node_modules/@babel/code-frame": {
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
+      "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
+      "dev": true,
+      "dependencies": {
+        "@babel/highlight": "^7.18.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
     "node_modules/jest-snapshot/node_modules/@jest/types": {
       "version": "27.5.1",
       "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz",
@@ -8935,6 +10030,26 @@
         "url": "https://github.com/chalk/chalk?sponsor=1"
       }
     },
+    "node_modules/jest-snapshot/node_modules/jest-message-util": {
+      "version": "27.5.1",
+      "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz",
+      "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==",
+      "dev": true,
+      "dependencies": {
+        "@babel/code-frame": "^7.12.13",
+        "@jest/types": "^27.5.1",
+        "@types/stack-utils": "^2.0.0",
+        "chalk": "^4.0.0",
+        "graceful-fs": "^4.2.9",
+        "micromatch": "^4.0.4",
+        "pretty-format": "^27.5.1",
+        "slash": "^3.0.0",
+        "stack-utils": "^2.0.3"
+      },
+      "engines": {
+        "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+      }
+    },
     "node_modules/jest-snapshot/node_modules/pretty-format": {
       "version": "27.5.1",
       "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
@@ -9322,9 +10437,9 @@
       }
     },
     "node_modules/jsdom/node_modules/acorn": {
-      "version": "8.7.1",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz",
-      "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==",
+      "version": "8.8.0",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz",
+      "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==",
       "dev": true,
       "bin": {
         "acorn": "bin/acorn"
@@ -10065,16 +11180,16 @@
       "dev": true
     },
     "node_modules/next": {
-      "version": "12.2.3",
-      "resolved": "https://registry.npmjs.org/next/-/next-12.2.3.tgz",
-      "integrity": "sha512-TA0tmSA6Dk6S6kfvCNbF7CWYW8468gZUxr/3/30z4KvAQbXnl2ASYZElVe7q/hBW/1F1ee0tSBlHa4/sn+ZIBw==",
+      "version": "12.2.5",
+      "resolved": "https://registry.npmjs.org/next/-/next-12.2.5.tgz",
+      "integrity": "sha512-tBdjqX5XC/oFs/6gxrZhjmiq90YWizUYU6qOWAfat7zJwrwapJ+BYgX2PmiacunXMaRpeVT4vz5MSPSLgNkrpA==",
       "dev": true,
       "dependencies": {
-        "@next/env": "12.2.3",
+        "@next/env": "12.2.5",
         "@swc/helpers": "0.4.3",
         "caniuse-lite": "^1.0.30001332",
         "postcss": "8.4.14",
-        "styled-jsx": "5.0.2",
+        "styled-jsx": "5.0.4",
         "use-sync-external-store": "1.2.0"
       },
       "bin": {
@@ -10084,19 +11199,19 @@
         "node": ">=12.22.0"
       },
       "optionalDependencies": {
-        "@next/swc-android-arm-eabi": "12.2.3",
-        "@next/swc-android-arm64": "12.2.3",
-        "@next/swc-darwin-arm64": "12.2.3",
-        "@next/swc-darwin-x64": "12.2.3",
-        "@next/swc-freebsd-x64": "12.2.3",
-        "@next/swc-linux-arm-gnueabihf": "12.2.3",
-        "@next/swc-linux-arm64-gnu": "12.2.3",
-        "@next/swc-linux-arm64-musl": "12.2.3",
-        "@next/swc-linux-x64-gnu": "12.2.3",
-        "@next/swc-linux-x64-musl": "12.2.3",
-        "@next/swc-win32-arm64-msvc": "12.2.3",
-        "@next/swc-win32-ia32-msvc": "12.2.3",
-        "@next/swc-win32-x64-msvc": "12.2.3"
+        "@next/swc-android-arm-eabi": "12.2.5",
+        "@next/swc-android-arm64": "12.2.5",
+        "@next/swc-darwin-arm64": "12.2.5",
+        "@next/swc-darwin-x64": "12.2.5",
+        "@next/swc-freebsd-x64": "12.2.5",
+        "@next/swc-linux-arm-gnueabihf": "12.2.5",
+        "@next/swc-linux-arm64-gnu": "12.2.5",
+        "@next/swc-linux-arm64-musl": "12.2.5",
+        "@next/swc-linux-x64-gnu": "12.2.5",
+        "@next/swc-linux-x64-musl": "12.2.5",
+        "@next/swc-win32-arm64-msvc": "12.2.5",
+        "@next/swc-win32-ia32-msvc": "12.2.5",
+        "@next/swc-win32-x64-msvc": "12.2.5"
       },
       "peerDependencies": {
         "fibers": ">= 3.1.0",
@@ -10177,9 +11292,9 @@
       }
     },
     "node_modules/nwsapi": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz",
-      "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==",
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.2.tgz",
+      "integrity": "sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==",
       "dev": true
     },
     "node_modules/oauth-sign": {
@@ -11884,9 +12999,9 @@
       }
     },
     "node_modules/signal-exit": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
-      "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
+      "version": "3.0.7",
+      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+      "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
       "dev": true
     },
     "node_modules/sisteransi": {
@@ -12264,9 +13379,9 @@
       }
     },
     "node_modules/styled-jsx": {
-      "version": "5.0.2",
-      "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.0.2.tgz",
-      "integrity": "sha512-LqPQrbBh3egD57NBcHET4qcgshPks+yblyhPlH2GY8oaDgKs8SK4C3dBh3oSJjgzJ3G5t1SYEZGHkP+QEpX9EQ==",
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.0.4.tgz",
+      "integrity": "sha512-sDFWLbg4zR+UkNzfk5lPilyIgtpddfxXEULxhujorr5jtePTUqiPDc5BC0v1NRqTr/WaFBGQQUoYToGlF4B2KQ==",
       "dev": true,
       "engines": {
         "node": ">= 12.0.0"
@@ -12296,9 +13411,9 @@
       }
     },
     "node_modules/supports-hyperlinks": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz",
-      "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==",
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz",
+      "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==",
       "dev": true,
       "dependencies": {
         "has-flag": "^4.0.0",
@@ -12640,13 +13755,10 @@
       }
     },
     "node_modules/ts-jest/node_modules/json5": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
-      "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
+      "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
       "dev": true,
-      "dependencies": {
-        "minimist": "^1.2.5"
-      },
       "bin": {
         "json5": "lib/cli.js"
       },
@@ -13094,9 +14206,9 @@
       }
     },
     "node_modules/v8-to-istanbul/node_modules/source-map": {
-      "version": "0.7.3",
-      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
-      "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
+      "version": "0.7.4",
+      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
+      "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
       "dev": true,
       "engines": {
         "node": ">= 8"
@@ -13355,9 +14467,9 @@
       }
     },
     "node_modules/ws": {
-      "version": "7.5.8",
-      "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.8.tgz",
-      "integrity": "sha512-ri1Id1WinAX5Jqn9HejiGb8crfRio0Qgu8+MtL36rlTA6RLsMdWt1Az/19A2Qij6uSHUMphEFaTKa4WG+UNHNw==",
+      "version": "7.5.9",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz",
+      "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==",
       "dev": true,
       "engines": {
         "node": ">=8.3.0"
@@ -13660,9 +14772,9 @@
       }
     },
     "@babel/helper-plugin-utils": {
-      "version": "7.17.12",
-      "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.17.12.tgz",
-      "integrity": "sha512-JDkf04mqtN3y4iAbO1hv9U2ARpPyPL1zqyWs/2WG1pgSq9llHFjStX5jdxb84himgJm+8Ng+x0oiWF/nw/XQKA==",
+      "version": "7.19.0",
+      "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz",
+      "integrity": "sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==",
       "dev": true
     },
     "@babel/helper-replace-supers": {
@@ -13696,9 +14808,9 @@
       }
     },
     "@babel/helper-validator-identifier": {
-      "version": "7.16.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz",
-      "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==",
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz",
+      "integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==",
       "dev": true
     },
     "@babel/helper-validator-option": {
@@ -13719,12 +14831,12 @@
       }
     },
     "@babel/highlight": {
-      "version": "7.17.12",
-      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.17.12.tgz",
-      "integrity": "sha512-7yykMVF3hfZY2jsHZEEgLc+3x4o1O+fYyULu11GynEUQNwB6lua+IIQn1FiJxNucd5UlyJryrwsOh8PL9Sn8Qg==",
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz",
+      "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==",
       "dev": true,
       "requires": {
-        "@babel/helper-validator-identifier": "^7.16.7",
+        "@babel/helper-validator-identifier": "^7.18.6",
         "chalk": "^2.0.0",
         "js-tokens": "^4.0.0"
       },
@@ -13896,12 +15008,12 @@
       }
     },
     "@babel/plugin-syntax-typescript": {
-      "version": "7.17.12",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.17.12.tgz",
-      "integrity": "sha512-TYY0SXFiO31YXtNg3HtFwNJHjLsAyIIhAhNWkQ5whPPS7HWUFlg9z0Ta4qAQNjQbP1wsSt/oKkmZ/4/WWdMUpw==",
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz",
+      "integrity": "sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA==",
       "dev": true,
       "requires": {
-        "@babel/helper-plugin-utils": "^7.17.12"
+        "@babel/helper-plugin-utils": "^7.18.6"
       }
     },
     "@babel/runtime": {
@@ -14055,6 +15167,84 @@
         }
       }
     },
+    "@edge-runtime/jest-environment": {
+      "version": "1.1.0-beta.31",
+      "resolved": "https://registry.npmjs.org/@edge-runtime/jest-environment/-/jest-environment-1.1.0-beta.31.tgz",
+      "integrity": "sha512-a65LVlCMkwkMxg8RjhEY5o3OZFHzMnLZcGqL234h3HO7Ri1Vriorj330BcPSh2GUt4zFqTS/3+XmWE6ueJwAZg==",
+      "dev": true,
+      "requires": {
+        "@edge-runtime/vm": "^1.1.0-beta.31",
+        "@jest/environment": "28.1.3",
+        "@jest/fake-timers": "28.1.3",
+        "@jest/types": "28.1.3",
+        "jest-mock": "28.1.3",
+        "jest-util": "28.1.3"
+      },
+      "dependencies": {
+        "@jest/types": {
+          "version": "28.1.3",
+          "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz",
+          "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==",
+          "dev": true,
+          "requires": {
+            "@jest/schemas": "^28.1.3",
+            "@types/istanbul-lib-coverage": "^2.0.0",
+            "@types/istanbul-reports": "^3.0.0",
+            "@types/node": "*",
+            "@types/yargs": "^17.0.8",
+            "chalk": "^4.0.0"
+          }
+        },
+        "@types/yargs": {
+          "version": "17.0.12",
+          "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.12.tgz",
+          "integrity": "sha512-Nz4MPhecOFArtm81gFQvQqdV7XYCrWKx5uUt6GNHredFHn1i2mtWqXTON7EPXMtNi1qjtjEM/VCHDhcHsAMLXQ==",
+          "dev": true,
+          "requires": {
+            "@types/yargs-parser": "*"
+          }
+        },
+        "chalk": {
+          "version": "4.1.2",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+          "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "jest-util": {
+          "version": "28.1.3",
+          "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz",
+          "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==",
+          "dev": true,
+          "requires": {
+            "@jest/types": "^28.1.3",
+            "@types/node": "*",
+            "chalk": "^4.0.0",
+            "ci-info": "^3.2.0",
+            "graceful-fs": "^4.2.9",
+            "picomatch": "^2.2.3"
+          }
+        }
+      }
+    },
+    "@edge-runtime/primitives": {
+      "version": "1.1.0-beta.31",
+      "resolved": "https://registry.npmjs.org/@edge-runtime/primitives/-/primitives-1.1.0-beta.31.tgz",
+      "integrity": "sha512-OO1x32aJoxgME1k77RVxVNsazs5NY/SNwYEN8ptlZ6DKUXn0eesXftDsmlypX/OU0ZeJc61/xNVUuoeyDGJDVA==",
+      "dev": true
+    },
+    "@edge-runtime/vm": {
+      "version": "1.1.0-beta.31",
+      "resolved": "https://registry.npmjs.org/@edge-runtime/vm/-/vm-1.1.0-beta.31.tgz",
+      "integrity": "sha512-D3JW32u7LSTt0KbphGWx2F41jId7BY8H0Awr25PTRFWroqohfWo1C2huOh7/Yyn4qeyJOVEuxWeTzvbSkTyyTg==",
+      "dev": true,
+      "requires": {
+        "@edge-runtime/primitives": "^1.1.0-beta.31"
+      }
+    },
     "@eslint/eslintrc": {
       "version": "0.4.3",
       "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz",
@@ -14192,6 +15382,15 @@
         "slash": "^3.0.0"
       },
       "dependencies": {
+        "@babel/code-frame": {
+          "version": "7.18.6",
+          "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
+          "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
+          "dev": true,
+          "requires": {
+            "@babel/highlight": "^7.18.6"
+          }
+        },
         "@jest/types": {
           "version": "27.5.1",
           "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz",
@@ -14223,6 +15422,48 @@
             "ansi-styles": "^4.1.0",
             "supports-color": "^7.1.0"
           }
+        },
+        "jest-message-util": {
+          "version": "27.5.1",
+          "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz",
+          "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "^7.12.13",
+            "@jest/types": "^27.5.1",
+            "@types/stack-utils": "^2.0.0",
+            "chalk": "^4.0.0",
+            "graceful-fs": "^4.2.9",
+            "micromatch": "^4.0.4",
+            "pretty-format": "^27.5.1",
+            "slash": "^3.0.0",
+            "stack-utils": "^2.0.3"
+          }
+        },
+        "pretty-format": {
+          "version": "27.5.1",
+          "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
+          "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^5.0.1",
+            "ansi-styles": "^5.0.0",
+            "react-is": "^17.0.1"
+          },
+          "dependencies": {
+            "ansi-styles": {
+              "version": "5.2.0",
+              "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+              "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+              "dev": true
+            }
+          }
+        },
+        "react-is": {
+          "version": "17.0.2",
+          "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+          "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+          "dev": true
         }
       }
     },
@@ -14262,6 +15503,15 @@
         "strip-ansi": "^6.0.0"
       },
       "dependencies": {
+        "@babel/code-frame": {
+          "version": "7.18.6",
+          "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
+          "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
+          "dev": true,
+          "requires": {
+            "@babel/highlight": "^7.18.6"
+          }
+        },
         "@jest/types": {
           "version": "27.5.1",
           "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz",
@@ -14281,50 +15531,93 @@
           "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
           "dev": true,
           "requires": {
-            "@types/yargs-parser": "*"
+            "@types/yargs-parser": "*"
+          }
+        },
+        "chalk": {
+          "version": "4.1.2",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+          "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "jest-message-util": {
+          "version": "27.5.1",
+          "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz",
+          "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "^7.12.13",
+            "@jest/types": "^27.5.1",
+            "@types/stack-utils": "^2.0.0",
+            "chalk": "^4.0.0",
+            "graceful-fs": "^4.2.9",
+            "micromatch": "^4.0.4",
+            "pretty-format": "^27.5.1",
+            "slash": "^3.0.0",
+            "stack-utils": "^2.0.3"
           }
         },
-        "chalk": {
-          "version": "4.1.2",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
-          "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+        "pretty-format": {
+          "version": "27.5.1",
+          "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
+          "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
           "dev": true,
           "requires": {
-            "ansi-styles": "^4.1.0",
-            "supports-color": "^7.1.0"
+            "ansi-regex": "^5.0.1",
+            "ansi-styles": "^5.0.0",
+            "react-is": "^17.0.1"
+          },
+          "dependencies": {
+            "ansi-styles": {
+              "version": "5.2.0",
+              "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+              "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+              "dev": true
+            }
           }
+        },
+        "react-is": {
+          "version": "17.0.2",
+          "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+          "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+          "dev": true
         }
       }
     },
     "@jest/environment": {
-      "version": "27.5.1",
-      "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz",
-      "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==",
+      "version": "28.1.3",
+      "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz",
+      "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==",
       "dev": true,
       "requires": {
-        "@jest/fake-timers": "^27.5.1",
-        "@jest/types": "^27.5.1",
+        "@jest/fake-timers": "^28.1.3",
+        "@jest/types": "^28.1.3",
         "@types/node": "*",
-        "jest-mock": "^27.5.1"
+        "jest-mock": "^28.1.3"
       },
       "dependencies": {
         "@jest/types": {
-          "version": "27.5.1",
-          "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz",
-          "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==",
+          "version": "28.1.3",
+          "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz",
+          "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==",
           "dev": true,
           "requires": {
+            "@jest/schemas": "^28.1.3",
             "@types/istanbul-lib-coverage": "^2.0.0",
             "@types/istanbul-reports": "^3.0.0",
             "@types/node": "*",
-            "@types/yargs": "^16.0.0",
+            "@types/yargs": "^17.0.8",
             "chalk": "^4.0.0"
           }
         },
         "@types/yargs": {
-          "version": "16.0.4",
-          "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
-          "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+          "version": "17.0.12",
+          "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.12.tgz",
+          "integrity": "sha512-Nz4MPhecOFArtm81gFQvQqdV7XYCrWKx5uUt6GNHredFHn1i2mtWqXTON7EPXMtNi1qjtjEM/VCHDhcHsAMLXQ==",
           "dev": true,
           "requires": {
             "@types/yargs-parser": "*"
@@ -14343,36 +15636,37 @@
       }
     },
     "@jest/fake-timers": {
-      "version": "27.5.1",
-      "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz",
-      "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==",
+      "version": "28.1.3",
+      "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz",
+      "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==",
       "dev": true,
       "requires": {
-        "@jest/types": "^27.5.1",
-        "@sinonjs/fake-timers": "^8.0.1",
+        "@jest/types": "^28.1.3",
+        "@sinonjs/fake-timers": "^9.1.2",
         "@types/node": "*",
-        "jest-message-util": "^27.5.1",
-        "jest-mock": "^27.5.1",
-        "jest-util": "^27.5.1"
+        "jest-message-util": "^28.1.3",
+        "jest-mock": "^28.1.3",
+        "jest-util": "^28.1.3"
       },
       "dependencies": {
         "@jest/types": {
-          "version": "27.5.1",
-          "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz",
-          "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==",
+          "version": "28.1.3",
+          "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz",
+          "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==",
           "dev": true,
           "requires": {
+            "@jest/schemas": "^28.1.3",
             "@types/istanbul-lib-coverage": "^2.0.0",
             "@types/istanbul-reports": "^3.0.0",
             "@types/node": "*",
-            "@types/yargs": "^16.0.0",
+            "@types/yargs": "^17.0.8",
             "chalk": "^4.0.0"
           }
         },
         "@types/yargs": {
-          "version": "16.0.4",
-          "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
-          "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+          "version": "17.0.12",
+          "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.12.tgz",
+          "integrity": "sha512-Nz4MPhecOFArtm81gFQvQqdV7XYCrWKx5uUt6GNHredFHn1i2mtWqXTON7EPXMtNi1qjtjEM/VCHDhcHsAMLXQ==",
           "dev": true,
           "requires": {
             "@types/yargs-parser": "*"
@@ -14387,6 +15681,20 @@
             "ansi-styles": "^4.1.0",
             "supports-color": "^7.1.0"
           }
+        },
+        "jest-util": {
+          "version": "28.1.3",
+          "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz",
+          "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==",
+          "dev": true,
+          "requires": {
+            "@jest/types": "^28.1.3",
+            "@types/node": "*",
+            "chalk": "^4.0.0",
+            "ci-info": "^3.2.0",
+            "graceful-fs": "^4.2.9",
+            "picomatch": "^2.2.3"
+          }
         }
       }
     },
@@ -14401,6 +15709,41 @@
         "expect": "^27.5.1"
       },
       "dependencies": {
+        "@babel/code-frame": {
+          "version": "7.18.6",
+          "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
+          "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
+          "dev": true,
+          "requires": {
+            "@babel/highlight": "^7.18.6"
+          }
+        },
+        "@jest/environment": {
+          "version": "27.5.1",
+          "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz",
+          "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==",
+          "dev": true,
+          "requires": {
+            "@jest/fake-timers": "^27.5.1",
+            "@jest/types": "^27.5.1",
+            "@types/node": "*",
+            "jest-mock": "^27.5.1"
+          }
+        },
+        "@jest/fake-timers": {
+          "version": "27.5.1",
+          "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz",
+          "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==",
+          "dev": true,
+          "requires": {
+            "@jest/types": "^27.5.1",
+            "@sinonjs/fake-timers": "^8.0.1",
+            "@types/node": "*",
+            "jest-message-util": "^27.5.1",
+            "jest-mock": "^27.5.1",
+            "jest-util": "^27.5.1"
+          }
+        },
         "@jest/types": {
           "version": "27.5.1",
           "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz",
@@ -14414,6 +15757,15 @@
             "chalk": "^4.0.0"
           }
         },
+        "@sinonjs/fake-timers": {
+          "version": "8.1.0",
+          "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz",
+          "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==",
+          "dev": true,
+          "requires": {
+            "@sinonjs/commons": "^1.7.0"
+          }
+        },
         "@types/yargs": {
           "version": "16.0.4",
           "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
@@ -14432,6 +15784,58 @@
             "ansi-styles": "^4.1.0",
             "supports-color": "^7.1.0"
           }
+        },
+        "jest-message-util": {
+          "version": "27.5.1",
+          "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz",
+          "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "^7.12.13",
+            "@jest/types": "^27.5.1",
+            "@types/stack-utils": "^2.0.0",
+            "chalk": "^4.0.0",
+            "graceful-fs": "^4.2.9",
+            "micromatch": "^4.0.4",
+            "pretty-format": "^27.5.1",
+            "slash": "^3.0.0",
+            "stack-utils": "^2.0.3"
+          }
+        },
+        "jest-mock": {
+          "version": "27.5.1",
+          "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz",
+          "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==",
+          "dev": true,
+          "requires": {
+            "@jest/types": "^27.5.1",
+            "@types/node": "*"
+          }
+        },
+        "pretty-format": {
+          "version": "27.5.1",
+          "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
+          "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^5.0.1",
+            "ansi-styles": "^5.0.0",
+            "react-is": "^17.0.1"
+          },
+          "dependencies": {
+            "ansi-styles": {
+              "version": "5.2.0",
+              "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+              "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+              "dev": true
+            }
+          }
+        },
+        "react-is": {
+          "version": "17.0.2",
+          "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+          "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+          "dev": true
         }
       }
     },
@@ -14502,6 +15906,15 @@
         }
       }
     },
+    "@jest/schemas": {
+      "version": "28.1.3",
+      "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz",
+      "integrity": "sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==",
+      "dev": true,
+      "requires": {
+        "@sinclair/typebox": "^0.24.1"
+      }
+    },
     "@jest/source-map": {
       "version": "27.5.1",
       "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz",
@@ -14663,99 +16076,99 @@
       }
     },
     "@next/env": {
-      "version": "12.2.3",
-      "resolved": "https://registry.npmjs.org/@next/env/-/env-12.2.3.tgz",
-      "integrity": "sha512-2lWKP5Xcvnor70NaaROZXBvU8z9mFReePCG8NhZw6NyNGnPvC+8s+Cre/63LAB1LKzWw/e9bZJnQUg0gYFRb2Q==",
+      "version": "12.2.5",
+      "resolved": "https://registry.npmjs.org/@next/env/-/env-12.2.5.tgz",
+      "integrity": "sha512-vLPLV3cpPGjUPT3PjgRj7e3nio9t6USkuew3JE/jMeon/9Mvp1WyR18v3iwnCuX7eUAm1HmAbJHHLAbcu/EJcw==",
       "dev": true
     },
     "@next/swc-android-arm-eabi": {
-      "version": "12.2.3",
-      "resolved": "https://registry.npmjs.org/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-12.2.3.tgz",
-      "integrity": "sha512-JxmCW9XB5PYnkGE67BdnBTdqW0SW6oMCiPMHLdjeRi4T3U4JJKJGnjQld99+6TPOfPWigtw3W7Cijp5gc+vJ/w==",
+      "version": "12.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-12.2.5.tgz",
+      "integrity": "sha512-cPWClKxGhgn2dLWnspW+7psl3MoLQUcNqJqOHk2BhNcou9ARDtC0IjQkKe5qcn9qg7I7U83Gp1yh2aesZfZJMA==",
       "dev": true,
       "optional": true
     },
     "@next/swc-android-arm64": {
-      "version": "12.2.3",
-      "resolved": "https://registry.npmjs.org/@next/swc-android-arm64/-/swc-android-arm64-12.2.3.tgz",
-      "integrity": "sha512-3l4zXpWnzy0fqoedsFRxzMy/eGlMMqn6IwPEuBmtEQ4h7srmQFHyT+Bk+eVHb0o1RQ7/TloAa+mu8JX5tz/5tA==",
+      "version": "12.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-android-arm64/-/swc-android-arm64-12.2.5.tgz",
+      "integrity": "sha512-vMj0efliXmC5b7p+wfcQCX0AfU8IypjkzT64GiKJD9PgiA3IILNiGJr1fw2lyUDHkjeWx/5HMlMEpLnTsQslwg==",
       "dev": true,
       "optional": true
     },
     "@next/swc-darwin-arm64": {
-      "version": "12.2.3",
-      "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-12.2.3.tgz",
-      "integrity": "sha512-eutDO/RH6pf7+8zHo3i2GKLhF0qaMtxWpY8k3Oa1k+CyrcJ0IxwkfH/x3f75jTMeCrThn6Uu8j3WeZOxvhto1Q==",
+      "version": "12.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-12.2.5.tgz",
+      "integrity": "sha512-VOPWbO5EFr6snla/WcxUKtvzGVShfs302TEMOtzYyWni6f9zuOetijJvVh9CCTzInnXAZMtHyNhefijA4HMYLg==",
       "dev": true,
       "optional": true
     },
     "@next/swc-darwin-x64": {
-      "version": "12.2.3",
-      "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-12.2.3.tgz",
-      "integrity": "sha512-lve+lnTiddXbcT3Lh2ujOFywQSEycTYQhuf6j6JrPu9oLQGS01kjIqqSj3/KMmSoppEnXo3BxkgYu+g2+ecHkA==",
+      "version": "12.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-12.2.5.tgz",
+      "integrity": "sha512-5o8bTCgAmtYOgauO/Xd27vW52G2/m3i5PX7MUYePquxXAnX73AAtqA3WgPXBRitEB60plSKZgOTkcpqrsh546A==",
       "dev": true,
       "optional": true
     },
     "@next/swc-freebsd-x64": {
-      "version": "12.2.3",
-      "resolved": "https://registry.npmjs.org/@next/swc-freebsd-x64/-/swc-freebsd-x64-12.2.3.tgz",
-      "integrity": "sha512-V4bZU1qBFkULTPW53phY8ypioh3EERzHu9YKAasm9RxU4dj+8c/4s60y+kbFkFEEpIUgEU6yNuYZRR4lHHbUGA==",
+      "version": "12.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-freebsd-x64/-/swc-freebsd-x64-12.2.5.tgz",
+      "integrity": "sha512-yYUbyup1JnznMtEBRkK4LT56N0lfK5qNTzr6/DEyDw5TbFVwnuy2hhLBzwCBkScFVjpFdfiC6SQAX3FrAZzuuw==",
       "dev": true,
       "optional": true
     },
     "@next/swc-linux-arm-gnueabihf": {
-      "version": "12.2.3",
-      "resolved": "https://registry.npmjs.org/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-12.2.3.tgz",
-      "integrity": "sha512-MWxS/i+XSEKdQE0ZmdYkPPrWKBi4JwMVaXdOW9J/T/sZJsHsLlSC9ErBcNolKAJEVka+tnw9oPRyRCKOj+q0sw==",
+      "version": "12.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-12.2.5.tgz",
+      "integrity": "sha512-2ZE2/G921Acks7UopJZVMgKLdm4vN4U0yuzvAMJ6KBavPzqESA2yHJlm85TV/K9gIjKhSk5BVtauIUntFRP8cg==",
       "dev": true,
       "optional": true
     },
     "@next/swc-linux-arm64-gnu": {
-      "version": "12.2.3",
-      "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-12.2.3.tgz",
-      "integrity": "sha512-ikXkqAmvEcWTzIQFDdmrUHLWzdDAF5s2pVsSpQn9rk/gK1i9webH1GRQd2bSM7JLuPBZSaYrNGvDTyHZdSEYlg==",
+      "version": "12.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-12.2.5.tgz",
+      "integrity": "sha512-/I6+PWVlz2wkTdWqhlSYYJ1pWWgUVva6SgX353oqTh8njNQp1SdFQuWDqk8LnM6ulheVfSsgkDzxrDaAQZnzjQ==",
       "dev": true,
       "optional": true
     },
     "@next/swc-linux-arm64-musl": {
-      "version": "12.2.3",
-      "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-12.2.3.tgz",
-      "integrity": "sha512-wE45gGFkeLLLnCoveKaBrdpYkkypl3qwNF2YhnfvfVK7etuu1O679LwClhCWinDVBr+KOkmyHok00Z+0uI1ycg==",
+      "version": "12.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-12.2.5.tgz",
+      "integrity": "sha512-LPQRelfX6asXyVr59p5sTpx5l+0yh2Vjp/R8Wi4X9pnqcayqT4CUJLiHqCvZuLin3IsFdisJL0rKHMoaZLRfmg==",
       "dev": true,
       "optional": true
     },
     "@next/swc-linux-x64-gnu": {
-      "version": "12.2.3",
-      "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-12.2.3.tgz",
-      "integrity": "sha512-MbFI6413VSXiREzHwYD8YAJLTknBaC+bmjXgdHEEdloeOuBFQGE3NWn3izOCTy8kV+s98VDQO8au7EKKs+bW0g==",
+      "version": "12.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-12.2.5.tgz",
+      "integrity": "sha512-0szyAo8jMCClkjNK0hknjhmAngUppoRekW6OAezbEYwHXN/VNtsXbfzgYOqjKWxEx3OoAzrT3jLwAF0HdX2MEw==",
       "dev": true,
       "optional": true
     },
     "@next/swc-linux-x64-musl": {
-      "version": "12.2.3",
-      "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-12.2.3.tgz",
-      "integrity": "sha512-jMBD0Va6fInbPih/dNySlNY2RpjkK6MXS+UGVEvuTswl1MZr+iahvurmshwGKpjaRwVU4DSFMD8+gfWxsTFs1Q==",
+      "version": "12.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-12.2.5.tgz",
+      "integrity": "sha512-zg/Y6oBar1yVnW6Il1I/08/2ukWtOG6s3acdJdEyIdsCzyQi4RLxbbhkD/EGQyhqBvd3QrC6ZXQEXighQUAZ0g==",
       "dev": true,
       "optional": true
     },
     "@next/swc-win32-arm64-msvc": {
-      "version": "12.2.3",
-      "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-12.2.3.tgz",
-      "integrity": "sha512-Cq8ToPdc0jQP2C7pjChYctAsEe7+lO/B826ZCK5xFzobuHPiCyJ2Mzx/nEQwCY4SpYkeJQtCbwlCz5iyGW5zGg==",
+      "version": "12.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-12.2.5.tgz",
+      "integrity": "sha512-3/90DRNSqeeSRMMEhj4gHHQlLhhKg5SCCoYfE3kBjGpE63EfnblYUqsszGGZ9ekpKL/R4/SGB40iCQr8tR5Jiw==",
       "dev": true,
       "optional": true
     },
     "@next/swc-win32-ia32-msvc": {
-      "version": "12.2.3",
-      "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-12.2.3.tgz",
-      "integrity": "sha512-BtFq4c8IpeB0sDhJMHJFgm86rPkOvmYI8k3De8Y2kgNVWSeLQ0Q929PWf7e+GqcX1015ei/gEB41ZH8Iw49NzA==",
+      "version": "12.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-12.2.5.tgz",
+      "integrity": "sha512-hGLc0ZRAwnaPL4ulwpp4D2RxmkHQLuI8CFOEEHdzZpS63/hMVzv81g8jzYA0UXbb9pus/iTc3VRbVbAM03SRrw==",
       "dev": true,
       "optional": true
     },
     "@next/swc-win32-x64-msvc": {
-      "version": "12.2.3",
-      "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-12.2.3.tgz",
-      "integrity": "sha512-huSNb98KSG77Kl96CoPgCwom28aamuUsPpRmn/4s9L0RNbbHVSkp9E6HA4yOAykZCEuWcdNsRLbVVuAbt8rtIw==",
+      "version": "12.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-12.2.5.tgz",
+      "integrity": "sha512-7h5/ahY7NeaO2xygqVrSG/Y8Vs4cdjxIjowTZ5W6CKoTKn7tmnuxlUc2h74x06FKmbhAd9agOjr/AOKyxYYm9Q==",
       "dev": true,
       "optional": true
     },
@@ -14813,6 +16226,12 @@
       "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz",
       "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ=="
     },
+    "@sinclair/typebox": {
+      "version": "0.24.38",
+      "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.38.tgz",
+      "integrity": "sha512-IbYB6vdhLFmzGEyXXEdFAJKyq7S4/RsivkgxNzs/LzwYuUJHmeNQ0cHkjG/Yqm6VgUzzZDLMZAf0XgeeaZAocA==",
+      "dev": true
+    },
     "@sindresorhus/is": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.0.0.tgz",
@@ -14828,9 +16247,9 @@
       }
     },
     "@sinonjs/fake-timers": {
-      "version": "8.1.0",
-      "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz",
-      "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==",
+      "version": "9.1.2",
+      "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz",
+      "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==",
       "dev": true,
       "requires": {
         "@sinonjs/commons": "^1.7.0"
@@ -14996,9 +16415,9 @@
       }
     },
     "@types/babel__traverse": {
-      "version": "7.14.2",
-      "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz",
-      "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==",
+      "version": "7.18.1",
+      "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.1.tgz",
+      "integrity": "sha512-FSdLaZh2UxaMuLp9lixWaHq/golWTRWOnRsAXzDTDSDOQLuZb1nsdCt6pJSPWSEQt2eFZ2YVk3oYhn+1kLMeMA==",
       "dev": true,
       "requires": {
         "@babel/types": "^7.3.0"
@@ -15239,9 +16658,9 @@
       }
     },
     "@types/prettier": {
-      "version": "2.6.3",
-      "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.3.tgz",
-      "integrity": "sha512-ymZk3LEC/fsut+/Q5qejp6R9O1rMxz3XaRHDV6kX8MrGAhOSPqVARbDi+EZvInBpw+BnCX3TD240byVkOfQsHg==",
+      "version": "2.7.0",
+      "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.0.tgz",
+      "integrity": "sha512-RI1L7N4JnW5gQw2spvL7Sllfuf1SaHdrZpCHiBlCXjIlufi1SMNnbu2teze3/QE67Fg2tBlH7W+mi4hVNk4p0A==",
       "dev": true
     },
     "@types/prop-types": {
@@ -17128,9 +18547,9 @@
       "dev": true
     },
     "decimal.js": {
-      "version": "10.3.1",
-      "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz",
-      "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==",
+      "version": "10.4.0",
+      "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.0.tgz",
+      "integrity": "sha512-Nv6ENEzyPQ6AItkGwLE2PGKinZZ9g59vSh2BeH6NqPu0OTKZ5ruJsVqh/orbAnqXc9pBbgXAIrc2EyaCj8NpGg==",
       "dev": true
     },
     "decode-uri-component": {
@@ -17515,7 +18934,7 @@
         "type-check": {
           "version": "0.3.2",
           "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
-          "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
+          "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==",
           "dev": true,
           "requires": {
             "prelude-ls": "~1.1.2"
@@ -17960,6 +19379,15 @@
         "jest-message-util": "^27.5.1"
       },
       "dependencies": {
+        "@babel/code-frame": {
+          "version": "7.18.6",
+          "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
+          "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
+          "dev": true,
+          "requires": {
+            "@babel/highlight": "^7.18.6"
+          }
+        },
         "@jest/types": {
           "version": "27.5.1",
           "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz",
@@ -17991,6 +19419,48 @@
             "ansi-styles": "^4.1.0",
             "supports-color": "^7.1.0"
           }
+        },
+        "jest-message-util": {
+          "version": "27.5.1",
+          "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz",
+          "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "^7.12.13",
+            "@jest/types": "^27.5.1",
+            "@types/stack-utils": "^2.0.0",
+            "chalk": "^4.0.0",
+            "graceful-fs": "^4.2.9",
+            "micromatch": "^4.0.4",
+            "pretty-format": "^27.5.1",
+            "slash": "^3.0.0",
+            "stack-utils": "^2.0.3"
+          }
+        },
+        "pretty-format": {
+          "version": "27.5.1",
+          "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
+          "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^5.0.1",
+            "ansi-styles": "^5.0.0",
+            "react-is": "^17.0.1"
+          },
+          "dependencies": {
+            "ansi-styles": {
+              "version": "5.2.0",
+              "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+              "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+              "dev": true
+            }
+          }
+        },
+        "react-is": {
+          "version": "17.0.2",
+          "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+          "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+          "dev": true
         }
       }
     },
@@ -19017,9 +20487,9 @@
       }
     },
     "istanbul-reports": {
-      "version": "3.1.4",
-      "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.4.tgz",
-      "integrity": "sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw==",
+      "version": "3.1.5",
+      "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz",
+      "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==",
       "dev": true,
       "requires": {
         "html-escaper": "^2.0.0",
@@ -19162,6 +20632,41 @@
         "throat": "^6.0.1"
       },
       "dependencies": {
+        "@babel/code-frame": {
+          "version": "7.18.6",
+          "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
+          "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
+          "dev": true,
+          "requires": {
+            "@babel/highlight": "^7.18.6"
+          }
+        },
+        "@jest/environment": {
+          "version": "27.5.1",
+          "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz",
+          "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==",
+          "dev": true,
+          "requires": {
+            "@jest/fake-timers": "^27.5.1",
+            "@jest/types": "^27.5.1",
+            "@types/node": "*",
+            "jest-mock": "^27.5.1"
+          }
+        },
+        "@jest/fake-timers": {
+          "version": "27.5.1",
+          "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz",
+          "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==",
+          "dev": true,
+          "requires": {
+            "@jest/types": "^27.5.1",
+            "@sinonjs/fake-timers": "^8.0.1",
+            "@types/node": "*",
+            "jest-message-util": "^27.5.1",
+            "jest-mock": "^27.5.1",
+            "jest-util": "^27.5.1"
+          }
+        },
         "@jest/types": {
           "version": "27.5.1",
           "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz",
@@ -19175,6 +20680,15 @@
             "chalk": "^4.0.0"
           }
         },
+        "@sinonjs/fake-timers": {
+          "version": "8.1.0",
+          "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz",
+          "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==",
+          "dev": true,
+          "requires": {
+            "@sinonjs/commons": "^1.7.0"
+          }
+        },
         "@types/yargs": {
           "version": "16.0.4",
           "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
@@ -19194,6 +20708,33 @@
             "supports-color": "^7.1.0"
           }
         },
+        "jest-message-util": {
+          "version": "27.5.1",
+          "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz",
+          "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "^7.12.13",
+            "@jest/types": "^27.5.1",
+            "@types/stack-utils": "^2.0.0",
+            "chalk": "^4.0.0",
+            "graceful-fs": "^4.2.9",
+            "micromatch": "^4.0.4",
+            "pretty-format": "^27.5.1",
+            "slash": "^3.0.0",
+            "stack-utils": "^2.0.3"
+          }
+        },
+        "jest-mock": {
+          "version": "27.5.1",
+          "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz",
+          "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==",
+          "dev": true,
+          "requires": {
+            "@jest/types": "^27.5.1",
+            "@types/node": "*"
+          }
+        },
         "pretty-format": {
           "version": "27.5.1",
           "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
@@ -19511,6 +21052,41 @@
         "jsdom": "^16.6.0"
       },
       "dependencies": {
+        "@babel/code-frame": {
+          "version": "7.18.6",
+          "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
+          "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
+          "dev": true,
+          "requires": {
+            "@babel/highlight": "^7.18.6"
+          }
+        },
+        "@jest/environment": {
+          "version": "27.5.1",
+          "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz",
+          "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==",
+          "dev": true,
+          "requires": {
+            "@jest/fake-timers": "^27.5.1",
+            "@jest/types": "^27.5.1",
+            "@types/node": "*",
+            "jest-mock": "^27.5.1"
+          }
+        },
+        "@jest/fake-timers": {
+          "version": "27.5.1",
+          "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz",
+          "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==",
+          "dev": true,
+          "requires": {
+            "@jest/types": "^27.5.1",
+            "@sinonjs/fake-timers": "^8.0.1",
+            "@types/node": "*",
+            "jest-message-util": "^27.5.1",
+            "jest-mock": "^27.5.1",
+            "jest-util": "^27.5.1"
+          }
+        },
         "@jest/types": {
           "version": "27.5.1",
           "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz",
@@ -19524,6 +21100,15 @@
             "chalk": "^4.0.0"
           }
         },
+        "@sinonjs/fake-timers": {
+          "version": "8.1.0",
+          "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz",
+          "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==",
+          "dev": true,
+          "requires": {
+            "@sinonjs/commons": "^1.7.0"
+          }
+        },
         "@types/yargs": {
           "version": "16.0.4",
           "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
@@ -19542,6 +21127,58 @@
             "ansi-styles": "^4.1.0",
             "supports-color": "^7.1.0"
           }
+        },
+        "jest-message-util": {
+          "version": "27.5.1",
+          "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz",
+          "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "^7.12.13",
+            "@jest/types": "^27.5.1",
+            "@types/stack-utils": "^2.0.0",
+            "chalk": "^4.0.0",
+            "graceful-fs": "^4.2.9",
+            "micromatch": "^4.0.4",
+            "pretty-format": "^27.5.1",
+            "slash": "^3.0.0",
+            "stack-utils": "^2.0.3"
+          }
+        },
+        "jest-mock": {
+          "version": "27.5.1",
+          "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz",
+          "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==",
+          "dev": true,
+          "requires": {
+            "@jest/types": "^27.5.1",
+            "@types/node": "*"
+          }
+        },
+        "pretty-format": {
+          "version": "27.5.1",
+          "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
+          "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^5.0.1",
+            "ansi-styles": "^5.0.0",
+            "react-is": "^17.0.1"
+          },
+          "dependencies": {
+            "ansi-styles": {
+              "version": "5.2.0",
+              "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+              "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+              "dev": true
+            }
+          }
+        },
+        "react-is": {
+          "version": "17.0.2",
+          "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+          "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+          "dev": true
         }
       }
     },
@@ -19559,6 +21196,41 @@
         "jest-util": "^27.5.1"
       },
       "dependencies": {
+        "@babel/code-frame": {
+          "version": "7.18.6",
+          "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
+          "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
+          "dev": true,
+          "requires": {
+            "@babel/highlight": "^7.18.6"
+          }
+        },
+        "@jest/environment": {
+          "version": "27.5.1",
+          "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz",
+          "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==",
+          "dev": true,
+          "requires": {
+            "@jest/fake-timers": "^27.5.1",
+            "@jest/types": "^27.5.1",
+            "@types/node": "*",
+            "jest-mock": "^27.5.1"
+          }
+        },
+        "@jest/fake-timers": {
+          "version": "27.5.1",
+          "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz",
+          "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==",
+          "dev": true,
+          "requires": {
+            "@jest/types": "^27.5.1",
+            "@sinonjs/fake-timers": "^8.0.1",
+            "@types/node": "*",
+            "jest-message-util": "^27.5.1",
+            "jest-mock": "^27.5.1",
+            "jest-util": "^27.5.1"
+          }
+        },
         "@jest/types": {
           "version": "27.5.1",
           "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz",
@@ -19572,6 +21244,15 @@
             "chalk": "^4.0.0"
           }
         },
+        "@sinonjs/fake-timers": {
+          "version": "8.1.0",
+          "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz",
+          "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==",
+          "dev": true,
+          "requires": {
+            "@sinonjs/commons": "^1.7.0"
+          }
+        },
         "@types/yargs": {
           "version": "16.0.4",
           "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
@@ -19590,6 +21271,58 @@
             "ansi-styles": "^4.1.0",
             "supports-color": "^7.1.0"
           }
+        },
+        "jest-message-util": {
+          "version": "27.5.1",
+          "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz",
+          "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "^7.12.13",
+            "@jest/types": "^27.5.1",
+            "@types/stack-utils": "^2.0.0",
+            "chalk": "^4.0.0",
+            "graceful-fs": "^4.2.9",
+            "micromatch": "^4.0.4",
+            "pretty-format": "^27.5.1",
+            "slash": "^3.0.0",
+            "stack-utils": "^2.0.3"
+          }
+        },
+        "jest-mock": {
+          "version": "27.5.1",
+          "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz",
+          "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==",
+          "dev": true,
+          "requires": {
+            "@jest/types": "^27.5.1",
+            "@types/node": "*"
+          }
+        },
+        "pretty-format": {
+          "version": "27.5.1",
+          "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
+          "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^5.0.1",
+            "ansi-styles": "^5.0.0",
+            "react-is": "^17.0.1"
+          },
+          "dependencies": {
+            "ansi-styles": {
+              "version": "5.2.0",
+              "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+              "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+              "dev": true
+            }
+          }
+        },
+        "react-is": {
+          "version": "17.0.2",
+          "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+          "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+          "dev": true
         }
       }
     },
@@ -19679,6 +21412,41 @@
         "throat": "^6.0.1"
       },
       "dependencies": {
+        "@babel/code-frame": {
+          "version": "7.18.6",
+          "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
+          "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
+          "dev": true,
+          "requires": {
+            "@babel/highlight": "^7.18.6"
+          }
+        },
+        "@jest/environment": {
+          "version": "27.5.1",
+          "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz",
+          "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==",
+          "dev": true,
+          "requires": {
+            "@jest/fake-timers": "^27.5.1",
+            "@jest/types": "^27.5.1",
+            "@types/node": "*",
+            "jest-mock": "^27.5.1"
+          }
+        },
+        "@jest/fake-timers": {
+          "version": "27.5.1",
+          "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz",
+          "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==",
+          "dev": true,
+          "requires": {
+            "@jest/types": "^27.5.1",
+            "@sinonjs/fake-timers": "^8.0.1",
+            "@types/node": "*",
+            "jest-message-util": "^27.5.1",
+            "jest-mock": "^27.5.1",
+            "jest-util": "^27.5.1"
+          }
+        },
         "@jest/types": {
           "version": "27.5.1",
           "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz",
@@ -19692,6 +21460,15 @@
             "chalk": "^4.0.0"
           }
         },
+        "@sinonjs/fake-timers": {
+          "version": "8.1.0",
+          "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz",
+          "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==",
+          "dev": true,
+          "requires": {
+            "@sinonjs/commons": "^1.7.0"
+          }
+        },
         "@types/yargs": {
           "version": "16.0.4",
           "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
@@ -19711,6 +21488,33 @@
             "supports-color": "^7.1.0"
           }
         },
+        "jest-message-util": {
+          "version": "27.5.1",
+          "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz",
+          "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "^7.12.13",
+            "@jest/types": "^27.5.1",
+            "@types/stack-utils": "^2.0.0",
+            "chalk": "^4.0.0",
+            "graceful-fs": "^4.2.9",
+            "micromatch": "^4.0.4",
+            "pretty-format": "^27.5.1",
+            "slash": "^3.0.0",
+            "stack-utils": "^2.0.3"
+          }
+        },
+        "jest-mock": {
+          "version": "27.5.1",
+          "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz",
+          "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==",
+          "dev": true,
+          "requires": {
+            "@jest/types": "^27.5.1",
+            "@types/node": "*"
+          }
+        },
         "pretty-format": {
           "version": "27.5.1",
           "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
@@ -19823,48 +21627,49 @@
       }
     },
     "jest-message-util": {
-      "version": "27.5.1",
-      "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz",
-      "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==",
+      "version": "28.1.3",
+      "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz",
+      "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==",
       "dev": true,
       "requires": {
         "@babel/code-frame": "^7.12.13",
-        "@jest/types": "^27.5.1",
+        "@jest/types": "^28.1.3",
         "@types/stack-utils": "^2.0.0",
         "chalk": "^4.0.0",
         "graceful-fs": "^4.2.9",
         "micromatch": "^4.0.4",
-        "pretty-format": "^27.5.1",
+        "pretty-format": "^28.1.3",
         "slash": "^3.0.0",
         "stack-utils": "^2.0.3"
       },
       "dependencies": {
         "@babel/code-frame": {
-          "version": "7.16.7",
-          "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz",
-          "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==",
+          "version": "7.18.6",
+          "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
+          "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
           "dev": true,
           "requires": {
-            "@babel/highlight": "^7.16.7"
+            "@babel/highlight": "^7.18.6"
           }
         },
         "@jest/types": {
-          "version": "27.5.1",
-          "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz",
-          "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==",
+          "version": "28.1.3",
+          "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz",
+          "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==",
           "dev": true,
           "requires": {
+            "@jest/schemas": "^28.1.3",
             "@types/istanbul-lib-coverage": "^2.0.0",
             "@types/istanbul-reports": "^3.0.0",
             "@types/node": "*",
-            "@types/yargs": "^16.0.0",
+            "@types/yargs": "^17.0.8",
             "chalk": "^4.0.0"
           }
         },
         "@types/yargs": {
-          "version": "16.0.4",
-          "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
-          "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+          "version": "17.0.12",
+          "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.12.tgz",
+          "integrity": "sha512-Nz4MPhecOFArtm81gFQvQqdV7XYCrWKx5uUt6GNHredFHn1i2mtWqXTON7EPXMtNi1qjtjEM/VCHDhcHsAMLXQ==",
           "dev": true,
           "requires": {
             "@types/yargs-parser": "*"
@@ -19881,14 +21686,15 @@
           }
         },
         "pretty-format": {
-          "version": "27.5.1",
-          "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
-          "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
+          "version": "28.1.3",
+          "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz",
+          "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==",
           "dev": true,
           "requires": {
+            "@jest/schemas": "^28.1.3",
             "ansi-regex": "^5.0.1",
             "ansi-styles": "^5.0.0",
-            "react-is": "^17.0.1"
+            "react-is": "^18.0.0"
           },
           "dependencies": {
             "ansi-styles": {
@@ -19900,40 +21706,41 @@
           }
         },
         "react-is": {
-          "version": "17.0.2",
-          "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
-          "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+          "version": "18.2.0",
+          "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+          "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
           "dev": true
         }
       }
     },
     "jest-mock": {
-      "version": "27.5.1",
-      "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz",
-      "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==",
+      "version": "28.1.3",
+      "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz",
+      "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==",
       "dev": true,
       "requires": {
-        "@jest/types": "^27.5.1",
+        "@jest/types": "^28.1.3",
         "@types/node": "*"
       },
       "dependencies": {
         "@jest/types": {
-          "version": "27.5.1",
-          "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz",
-          "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==",
+          "version": "28.1.3",
+          "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz",
+          "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==",
           "dev": true,
           "requires": {
+            "@jest/schemas": "^28.1.3",
             "@types/istanbul-lib-coverage": "^2.0.0",
             "@types/istanbul-reports": "^3.0.0",
             "@types/node": "*",
-            "@types/yargs": "^16.0.0",
+            "@types/yargs": "^17.0.8",
             "chalk": "^4.0.0"
           }
         },
         "@types/yargs": {
-          "version": "16.0.4",
-          "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
-          "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+          "version": "17.0.12",
+          "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.12.tgz",
+          "integrity": "sha512-Nz4MPhecOFArtm81gFQvQqdV7XYCrWKx5uUt6GNHredFHn1i2mtWqXTON7EPXMtNi1qjtjEM/VCHDhcHsAMLXQ==",
           "dev": true,
           "requires": {
             "@types/yargs-parser": "*"
@@ -20090,6 +21897,41 @@
         "throat": "^6.0.1"
       },
       "dependencies": {
+        "@babel/code-frame": {
+          "version": "7.18.6",
+          "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
+          "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
+          "dev": true,
+          "requires": {
+            "@babel/highlight": "^7.18.6"
+          }
+        },
+        "@jest/environment": {
+          "version": "27.5.1",
+          "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz",
+          "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==",
+          "dev": true,
+          "requires": {
+            "@jest/fake-timers": "^27.5.1",
+            "@jest/types": "^27.5.1",
+            "@types/node": "*",
+            "jest-mock": "^27.5.1"
+          }
+        },
+        "@jest/fake-timers": {
+          "version": "27.5.1",
+          "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz",
+          "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==",
+          "dev": true,
+          "requires": {
+            "@jest/types": "^27.5.1",
+            "@sinonjs/fake-timers": "^8.0.1",
+            "@types/node": "*",
+            "jest-message-util": "^27.5.1",
+            "jest-mock": "^27.5.1",
+            "jest-util": "^27.5.1"
+          }
+        },
         "@jest/types": {
           "version": "27.5.1",
           "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz",
@@ -20103,6 +21945,15 @@
             "chalk": "^4.0.0"
           }
         },
+        "@sinonjs/fake-timers": {
+          "version": "8.1.0",
+          "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz",
+          "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==",
+          "dev": true,
+          "requires": {
+            "@sinonjs/commons": "^1.7.0"
+          }
+        },
         "@types/yargs": {
           "version": "16.0.4",
           "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
@@ -20121,6 +21972,58 @@
             "ansi-styles": "^4.1.0",
             "supports-color": "^7.1.0"
           }
+        },
+        "jest-message-util": {
+          "version": "27.5.1",
+          "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz",
+          "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "^7.12.13",
+            "@jest/types": "^27.5.1",
+            "@types/stack-utils": "^2.0.0",
+            "chalk": "^4.0.0",
+            "graceful-fs": "^4.2.9",
+            "micromatch": "^4.0.4",
+            "pretty-format": "^27.5.1",
+            "slash": "^3.0.0",
+            "stack-utils": "^2.0.3"
+          }
+        },
+        "jest-mock": {
+          "version": "27.5.1",
+          "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz",
+          "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==",
+          "dev": true,
+          "requires": {
+            "@jest/types": "^27.5.1",
+            "@types/node": "*"
+          }
+        },
+        "pretty-format": {
+          "version": "27.5.1",
+          "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
+          "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^5.0.1",
+            "ansi-styles": "^5.0.0",
+            "react-is": "^17.0.1"
+          },
+          "dependencies": {
+            "ansi-styles": {
+              "version": "5.2.0",
+              "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+              "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+              "dev": true
+            }
+          }
+        },
+        "react-is": {
+          "version": "17.0.2",
+          "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+          "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+          "dev": true
         }
       }
     },
@@ -20154,6 +22057,41 @@
         "strip-bom": "^4.0.0"
       },
       "dependencies": {
+        "@babel/code-frame": {
+          "version": "7.18.6",
+          "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
+          "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
+          "dev": true,
+          "requires": {
+            "@babel/highlight": "^7.18.6"
+          }
+        },
+        "@jest/environment": {
+          "version": "27.5.1",
+          "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz",
+          "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==",
+          "dev": true,
+          "requires": {
+            "@jest/fake-timers": "^27.5.1",
+            "@jest/types": "^27.5.1",
+            "@types/node": "*",
+            "jest-mock": "^27.5.1"
+          }
+        },
+        "@jest/fake-timers": {
+          "version": "27.5.1",
+          "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz",
+          "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==",
+          "dev": true,
+          "requires": {
+            "@jest/types": "^27.5.1",
+            "@sinonjs/fake-timers": "^8.0.1",
+            "@types/node": "*",
+            "jest-message-util": "^27.5.1",
+            "jest-mock": "^27.5.1",
+            "jest-util": "^27.5.1"
+          }
+        },
         "@jest/types": {
           "version": "27.5.1",
           "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz",
@@ -20167,6 +22105,15 @@
             "chalk": "^4.0.0"
           }
         },
+        "@sinonjs/fake-timers": {
+          "version": "8.1.0",
+          "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz",
+          "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==",
+          "dev": true,
+          "requires": {
+            "@sinonjs/commons": "^1.7.0"
+          }
+        },
         "@types/yargs": {
           "version": "16.0.4",
           "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
@@ -20215,6 +22162,58 @@
           "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
           "dev": true
         },
+        "jest-message-util": {
+          "version": "27.5.1",
+          "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz",
+          "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "^7.12.13",
+            "@jest/types": "^27.5.1",
+            "@types/stack-utils": "^2.0.0",
+            "chalk": "^4.0.0",
+            "graceful-fs": "^4.2.9",
+            "micromatch": "^4.0.4",
+            "pretty-format": "^27.5.1",
+            "slash": "^3.0.0",
+            "stack-utils": "^2.0.3"
+          }
+        },
+        "jest-mock": {
+          "version": "27.5.1",
+          "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz",
+          "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==",
+          "dev": true,
+          "requires": {
+            "@jest/types": "^27.5.1",
+            "@types/node": "*"
+          }
+        },
+        "pretty-format": {
+          "version": "27.5.1",
+          "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
+          "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^5.0.1",
+            "ansi-styles": "^5.0.0",
+            "react-is": "^17.0.1"
+          },
+          "dependencies": {
+            "ansi-styles": {
+              "version": "5.2.0",
+              "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+              "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+              "dev": true
+            }
+          }
+        },
+        "react-is": {
+          "version": "17.0.2",
+          "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+          "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+          "dev": true
+        },
         "strip-bom": {
           "version": "4.0.0",
           "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
@@ -20263,6 +22262,15 @@
         "semver": "^7.3.2"
       },
       "dependencies": {
+        "@babel/code-frame": {
+          "version": "7.18.6",
+          "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
+          "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
+          "dev": true,
+          "requires": {
+            "@babel/highlight": "^7.18.6"
+          }
+        },
         "@jest/types": {
           "version": "27.5.1",
           "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz",
@@ -20295,6 +22303,23 @@
             "supports-color": "^7.1.0"
           }
         },
+        "jest-message-util": {
+          "version": "27.5.1",
+          "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz",
+          "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "^7.12.13",
+            "@jest/types": "^27.5.1",
+            "@types/stack-utils": "^2.0.0",
+            "chalk": "^4.0.0",
+            "graceful-fs": "^4.2.9",
+            "micromatch": "^4.0.4",
+            "pretty-format": "^27.5.1",
+            "slash": "^3.0.0",
+            "stack-utils": "^2.0.3"
+          }
+        },
         "pretty-format": {
           "version": "27.5.1",
           "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
@@ -20604,9 +22629,9 @@
       },
       "dependencies": {
         "acorn": {
-          "version": "8.7.1",
-          "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz",
-          "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==",
+          "version": "8.8.0",
+          "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz",
+          "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==",
           "dev": true
         },
         "form-data": {
@@ -21199,29 +23224,29 @@
       "dev": true
     },
     "next": {
-      "version": "12.2.3",
-      "resolved": "https://registry.npmjs.org/next/-/next-12.2.3.tgz",
-      "integrity": "sha512-TA0tmSA6Dk6S6kfvCNbF7CWYW8468gZUxr/3/30z4KvAQbXnl2ASYZElVe7q/hBW/1F1ee0tSBlHa4/sn+ZIBw==",
-      "dev": true,
-      "requires": {
-        "@next/env": "12.2.3",
-        "@next/swc-android-arm-eabi": "12.2.3",
-        "@next/swc-android-arm64": "12.2.3",
-        "@next/swc-darwin-arm64": "12.2.3",
-        "@next/swc-darwin-x64": "12.2.3",
-        "@next/swc-freebsd-x64": "12.2.3",
-        "@next/swc-linux-arm-gnueabihf": "12.2.3",
-        "@next/swc-linux-arm64-gnu": "12.2.3",
-        "@next/swc-linux-arm64-musl": "12.2.3",
-        "@next/swc-linux-x64-gnu": "12.2.3",
-        "@next/swc-linux-x64-musl": "12.2.3",
-        "@next/swc-win32-arm64-msvc": "12.2.3",
-        "@next/swc-win32-ia32-msvc": "12.2.3",
-        "@next/swc-win32-x64-msvc": "12.2.3",
+      "version": "12.2.5",
+      "resolved": "https://registry.npmjs.org/next/-/next-12.2.5.tgz",
+      "integrity": "sha512-tBdjqX5XC/oFs/6gxrZhjmiq90YWizUYU6qOWAfat7zJwrwapJ+BYgX2PmiacunXMaRpeVT4vz5MSPSLgNkrpA==",
+      "dev": true,
+      "requires": {
+        "@next/env": "12.2.5",
+        "@next/swc-android-arm-eabi": "12.2.5",
+        "@next/swc-android-arm64": "12.2.5",
+        "@next/swc-darwin-arm64": "12.2.5",
+        "@next/swc-darwin-x64": "12.2.5",
+        "@next/swc-freebsd-x64": "12.2.5",
+        "@next/swc-linux-arm-gnueabihf": "12.2.5",
+        "@next/swc-linux-arm64-gnu": "12.2.5",
+        "@next/swc-linux-arm64-musl": "12.2.5",
+        "@next/swc-linux-x64-gnu": "12.2.5",
+        "@next/swc-linux-x64-musl": "12.2.5",
+        "@next/swc-win32-arm64-msvc": "12.2.5",
+        "@next/swc-win32-ia32-msvc": "12.2.5",
+        "@next/swc-win32-x64-msvc": "12.2.5",
         "@swc/helpers": "0.4.3",
         "caniuse-lite": "^1.0.30001332",
         "postcss": "8.4.14",
-        "styled-jsx": "5.0.2",
+        "styled-jsx": "5.0.4",
         "use-sync-external-store": "1.2.0"
       }
     },
@@ -21270,9 +23295,9 @@
       }
     },
     "nwsapi": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz",
-      "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==",
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.2.tgz",
+      "integrity": "sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==",
       "dev": true
     },
     "oauth-sign": {
@@ -22556,9 +24581,9 @@
       }
     },
     "signal-exit": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
-      "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
+      "version": "3.0.7",
+      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+      "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
       "dev": true
     },
     "sisteransi": {
@@ -22843,9 +24868,9 @@
       "dev": true
     },
     "styled-jsx": {
-      "version": "5.0.2",
-      "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.0.2.tgz",
-      "integrity": "sha512-LqPQrbBh3egD57NBcHET4qcgshPks+yblyhPlH2GY8oaDgKs8SK4C3dBh3oSJjgzJ3G5t1SYEZGHkP+QEpX9EQ==",
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.0.4.tgz",
+      "integrity": "sha512-sDFWLbg4zR+UkNzfk5lPilyIgtpddfxXEULxhujorr5jtePTUqiPDc5BC0v1NRqTr/WaFBGQQUoYToGlF4B2KQ==",
       "dev": true,
       "requires": {}
     },
@@ -22859,9 +24884,9 @@
       }
     },
     "supports-hyperlinks": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz",
-      "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==",
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz",
+      "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==",
       "dev": true,
       "requires": {
         "has-flag": "^4.0.0",
@@ -23114,13 +25139,10 @@
       },
       "dependencies": {
         "json5": {
-          "version": "2.2.0",
-          "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
-          "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
-          "dev": true,
-          "requires": {
-            "minimist": "^1.2.5"
-          }
+          "version": "2.2.1",
+          "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
+          "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
+          "dev": true
         },
         "semver": {
           "version": "7.3.5",
@@ -23467,9 +25489,9 @@
       },
       "dependencies": {
         "source-map": {
-          "version": "0.7.3",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
-          "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
+          "version": "0.7.4",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
+          "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
           "dev": true
         }
       }
@@ -23681,9 +25703,9 @@
       }
     },
     "ws": {
-      "version": "7.5.8",
-      "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.8.tgz",
-      "integrity": "sha512-ri1Id1WinAX5Jqn9HejiGb8crfRio0Qgu8+MtL36rlTA6RLsMdWt1Az/19A2Qij6uSHUMphEFaTKa4WG+UNHNw==",
+      "version": "7.5.9",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz",
+      "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==",
       "dev": true,
       "requires": {}
     },
diff --git a/package.json b/package.json
index ca0c2c62..97767355 100644
--- a/package.json
+++ b/package.json
@@ -11,6 +11,8 @@
   "files": [
     "dist",
     "src",
+    "middleware.js",
+    "middleware.d.ts",
     "testing.js",
     "testing.d.ts"
   ],
@@ -61,6 +63,7 @@
   },
   "homepage": "https://github.com/auth0/nextjs-auth0#readme",
   "devDependencies": {
+    "@edge-runtime/jest-environment": "^1.1.0-beta.31",
     "@testing-library/jest-dom": "^5.11.9",
     "@testing-library/react": "^11.2.3",
     "@testing-library/react-hooks": "^5.0.3",
@@ -92,7 +95,7 @@
     "eslint-plugin-react": "^7.22.0",
     "eslint-plugin-react-hooks": "^4.2.0",
     "jest": "^27.2.0",
-    "next": "^12.1.6",
+    "next": "^12.2.5",
     "nock": "^13.0.5",
     "oidc-provider": "^7.6.0",
     "on-headers": "^1.0.2",
@@ -134,7 +137,12 @@
       "<rootDir>/src/**/*.*",
       "!<rootDir>/src/index.browser.ts",
       "!<rootDir>/src/index.ts",
-      "!<rootDir>/src/handlers/auth.ts"
+      "!<rootDir>/src/middleware.ts",
+      "!<rootDir>/src/instance.ts",
+      "!<rootDir>/src/handlers/auth.ts",
+      "!<rootDir>/src/auth0-session/config.ts",
+      "!<rootDir>/src/auth0-session/index.ts",
+      "!<rootDir>/src/auth0-session/session-cache.ts"
     ],
     "coverageReporters": [
       "lcov",
@@ -149,6 +157,7 @@
         "statements": 100
       }
     },
+    "coverageProvider": "v8",
     "preset": "ts-jest",
     "globalSetup": "./tests/global-setup.ts",
     "setupFilesAfterEnv": [
diff --git a/src/auth0-session/config.ts b/src/auth0-session/config.ts
index 19649220..51f3413c 100644
--- a/src/auth0-session/config.ts
+++ b/src/auth0-session/config.ts
@@ -1,5 +1,5 @@
-import { IncomingMessage } from 'http';
-import { AuthorizationParameters as OidcAuthorizationParameters } from 'openid-client';
+import type { IncomingMessage } from 'http';
+import type { AuthorizationParameters as OidcAuthorizationParameters } from 'openid-client';
 
 /**
  * Configuration properties.
diff --git a/src/auth0-session/cookie-store.ts b/src/auth0-session/cookie-store.ts
index b1cb6577..6a1409e4 100644
--- a/src/auth0-session/cookie-store.ts
+++ b/src/auth0-session/cookie-store.ts
@@ -1,10 +1,9 @@
 import { IncomingMessage, ServerResponse } from 'http';
-import { strict as assert, AssertionError } from 'assert';
 import * as jose from 'jose';
 import { CookieSerializeOptions, serialize } from 'cookie';
 import { encryption as deriveKey } from './utils/hkdf';
 import createDebug from './utils/debug';
-import Cookies from './utils/cookies';
+import { Cookies } from './utils/cookies';
 import { Config } from './config';
 
 const debug = createDebug('cookie-store');
@@ -15,13 +14,18 @@ const enc = 'A256GCM';
 
 type Header = { iat: number; uat: number; exp: number };
 const notNull = <T>(value: T | null): value is T => value !== null;
+const assert = (bool: boolean, msg: string) => {
+  if (!bool) {
+    throw new Error(msg);
+  }
+};
 
-export default class CookieStore {
+export default class CookieStore<Req = IncomingMessage, Res = ServerResponse> {
   private keys?: Uint8Array[];
 
   private chunkSize: number;
 
-  constructor(public config: Config) {
+  constructor(private config: Config, private Cookies: new () => Cookies) {
     const {
       cookie: { transient, ...cookieConfig },
       name: sessionName
@@ -54,7 +58,7 @@ export default class CookieStore {
   private async decrypt(jwe: string): Promise<jose.JWTDecryptResult> {
     const keys = await this.getKeys();
     let err;
-    for (let key of keys) {
+    for (const key of keys) {
       try {
         return await jose.jwtDecrypt(jwe, key);
       } catch (e) {
@@ -77,8 +81,8 @@ export default class CookieStore {
     return Math.min(uat + (rollingDuration as number), iat + absoluteDuration);
   }
 
-  public async read(req: any): Promise<[{ [key: string]: any }?, number?]> {
-    const cookies = Cookies.getAll(req);
+  public async read(req: Req): Promise<[{ [key: string]: any }?, number?]> {
+    const cookies = new this.Cookies().getAll(req);
     const { name: sessionName, rollingDuration, absoluteDuration } = this.config.session;
 
     let iat: number;
@@ -136,22 +140,15 @@ export default class CookieStore {
         return [payload, iat];
       }
     } catch (err) {
-      /* istanbul ignore else */
-      if (err instanceof AssertionError) {
-        debug('existing session was rejected because', err.message);
-      } else if (err instanceof jose.errors.JOSEError) {
-        debug('existing session was rejected because it could not be decrypted', err);
-      } else {
-        debug('unexpected error handling session', err);
-      }
+      debug('error handling session %O', err);
     }
 
     return [];
   }
 
   public async save(
-    req: IncomingMessage,
-    res: ServerResponse,
+    req: Req,
+    res: Res,
     session: { [key: string]: any } | undefined | null,
     createdAt?: number
   ): Promise<void> {
@@ -159,8 +156,8 @@ export default class CookieStore {
       cookie: { transient, ...cookieConfig },
       name: sessionName
     } = this.config.session;
-    const cookies = Cookies.getAll(req);
-    const cookieSetter = new Cookies();
+    const cookieSetter = new this.Cookies();
+    const cookies = cookieSetter.getAll(req);
 
     if (!session) {
       debug('clearing all matching session cookies');
diff --git a/src/auth0-session/get-config.ts b/src/auth0-session/get-config.ts
index 02b76215..9861b438 100644
--- a/src/auth0-session/get-config.ts
+++ b/src/auth0-session/get-config.ts
@@ -5,11 +5,7 @@ import { Config } from './config';
 const isHttps = /^https:/i;
 
 const paramsSchema = Joi.object({
-  secret: Joi.alternatives([
-    Joi.string().min(8),
-    Joi.binary().min(8),
-    Joi.array().items(Joi.string().min(8), Joi.binary().min(8))
-  ]).required(),
+  secret: Joi.alternatives([Joi.string().min(8), Joi.array().items(Joi.string().min(8))]).required(),
   session: Joi.object({
     rolling: Joi.boolean().optional().default(true),
     rollingDuration: Joi.when(Joi.ref('rolling'), {
diff --git a/src/auth0-session/index.ts b/src/auth0-session/index.ts
index 51a6a0cf..e48db5e1 100644
--- a/src/auth0-session/index.ts
+++ b/src/auth0-session/index.ts
@@ -1,3 +1,4 @@
+export { default as NodeCookies, Cookies } from './utils/cookies';
 export { default as CookieStore } from './cookie-store';
 export { default as TransientStore } from './transient-store';
 export { Config, SessionConfig, CookieConfig, LoginOptions, LogoutOptions, AuthorizationParameters } from './config';
diff --git a/src/auth0-session/session-cache.ts b/src/auth0-session/session-cache.ts
index 1f072390..5dcc1f75 100644
--- a/src/auth0-session/session-cache.ts
+++ b/src/auth0-session/session-cache.ts
@@ -1,10 +1,10 @@
-import { IncomingMessage, ServerResponse } from 'http';
-import { TokenSet } from 'openid-client';
+import type { TokenSet } from 'openid-client';
+import type { IncomingMessage, ServerResponse } from 'http';
 
-export interface SessionCache {
-  create(req: IncomingMessage, res: ServerResponse, session: { [key: string]: any }): Promise<void>;
-  delete(req: IncomingMessage, res: ServerResponse): Promise<void>;
-  isAuthenticated(req: IncomingMessage, res: ServerResponse): Promise<boolean>;
-  getIdToken(req: IncomingMessage, res: ServerResponse): Promise<string | undefined>;
-  fromTokenSet(tokenSet: TokenSet): { [key: string]: any };
+export interface SessionCache<Req = IncomingMessage, Res = ServerResponse, Session = { [key: string]: any }> {
+  create(req: Req, res: Res, session: Session): Promise<void>;
+  delete(req: Req, res: Res): Promise<void>;
+  isAuthenticated(req: Req, res: Res): Promise<boolean>;
+  getIdToken(req: Req, res: Res): Promise<string | undefined>;
+  fromTokenSet(tokenSet: TokenSet): Session;
 }
diff --git a/src/auth0-session/transient-store.ts b/src/auth0-session/transient-store.ts
index 16caa44f..e2b62c9e 100644
--- a/src/auth0-session/transient-store.ts
+++ b/src/auth0-session/transient-store.ts
@@ -2,7 +2,7 @@ import { IncomingMessage, ServerResponse } from 'http';
 import { generators } from 'openid-client';
 import * as jose from 'jose';
 import { signing as deriveKey } from './utils/hkdf';
-import Cookies from './utils/cookies';
+import NodeCookies from './utils/cookies';
 import { Config } from './config';
 
 export interface StoreOptions {
@@ -20,7 +20,7 @@ const getCookieValue = async (k: string, v: string, keys: Uint8Array[]): Promise
     payload: `${k}=${value}`,
     signature
   };
-  for (let key of keys) {
+  for (const key of keys) {
     try {
       await jose.flattenedVerify(flattenedJWS, key, {
         algorithms: ['HS256']
@@ -79,7 +79,7 @@ export default class TransientStore {
       path
     };
     const [signingKey] = await this.getKeys();
-    const cookieSetter = new Cookies();
+    const cookieSetter = new NodeCookies();
 
     {
       const cookieValue = await generateCookieValue(key, value, signingKey);
@@ -111,10 +111,10 @@ export default class TransientStore {
    * @return {String|undefined} Cookie value or undefined if cookie was not found.
    */
   async read(key: string, req: IncomingMessage, res: ServerResponse): Promise<string | undefined> {
-    const cookies = Cookies.getAll(req);
+    const cookies = new NodeCookies().getAll(req);
     const cookie = cookies[key];
     const cookieConfig = this.config.session.cookie;
-    const cookieSetter = new Cookies();
+    const cookieSetter = new NodeCookies();
 
     const verifyingKeys = await this.getKeys();
     let value = await getCookieValue(key, cookie, verifyingKeys);
diff --git a/src/auth0-session/utils/cookies.ts b/src/auth0-session/utils/cookies.ts
index c81fcff4..9ee36c3b 100644
--- a/src/auth0-session/utils/cookies.ts
+++ b/src/auth0-session/utils/cookies.ts
@@ -1,18 +1,18 @@
-import { IncomingMessage, ServerResponse } from 'http';
+import type { IncomingMessage, ServerResponse } from 'http';
 import { CookieSerializeOptions, parse, serialize } from 'cookie';
 
-export default class Cookies {
-  private cookies: string[];
+export abstract class Cookies {
+  protected cookies: string[];
 
   constructor() {
     this.cookies = [];
   }
 
-  set(name: string, value: string, options: CookieSerializeOptions = {}) {
+  set(name: string, value: string, options: CookieSerializeOptions = {}): void {
     this.cookies.push(serialize(name, value, options));
   }
 
-  clear(name: string, options: CookieSerializeOptions = {}) {
+  clear(name: string, options: CookieSerializeOptions = {}): void {
     const { domain, path, secure, sameSite } = options;
     const clearOptions: CookieSerializeOptions = {
       domain,
@@ -28,19 +28,34 @@ export default class Cookies {
     this.set(name, '', clearOptions);
   }
 
-  commit(res: ServerResponse, filterCookiePrefix?: string) {
-    let previousCookies = res.getHeader('Set-Cookie') || [];
-    if (!Array.isArray(previousCookies)) {
-      previousCookies = [previousCookies as string];
-    }
+  commit(res: unknown, filterCookiePrefix?: string): void {
+    let previousCookies = this.getSetCookieHeader(res);
     if (filterCookiePrefix) {
       const re = new RegExp(`^${filterCookiePrefix}(\\.\\d+)?=`);
       previousCookies = previousCookies.filter((cookie: string) => !re.test(cookie));
     }
-    res.setHeader('Set-Cookie', [...previousCookies, ...this.cookies]);
+    this.setSetCookieHeader(res, [...previousCookies, ...this.cookies]);
+  }
+
+  protected abstract getSetCookieHeader(res: unknown): string[];
+  protected abstract setSetCookieHeader(res: unknown, cookies: string[]): void;
+  abstract getAll(req: unknown): Record<string, string>;
+}
+
+export default class NodeCookies extends Cookies {
+  protected getSetCookieHeader(res: ServerResponse): string[] {
+    let cookies = res.getHeader('Set-Cookie') || [];
+    if (!Array.isArray(cookies)) {
+      cookies = [cookies as string];
+    }
+    return cookies;
+  }
+
+  protected setSetCookieHeader(res: ServerResponse, cookies: string[]): void {
+    res.setHeader('Set-Cookie', cookies);
   }
 
-  static getAll(req: IncomingMessage) {
+  getAll(req: IncomingMessage): Record<string, string> {
     return parse(req.headers.cookie || '');
   }
 }
diff --git a/src/config.ts b/src/config.ts
index bf089241..f0871110 100644
--- a/src/config.ts
+++ b/src/config.ts
@@ -1,6 +1,7 @@
 import { IncomingMessage } from 'http';
-import { AuthorizationParameters as OidcAuthorizationParameters } from 'openid-client';
-import { LoginOptions, DeepPartial, getConfig as getBaseConfig } from './auth0-session';
+import type { AuthorizationParameters as OidcAuthorizationParameters } from 'openid-client';
+import type { LoginOptions } from './auth0-session/config';
+import { DeepPartial, get as getBaseConfig } from './auth0-session/get-config';
 
 /**
  * @category server
@@ -305,6 +306,7 @@ export interface NextConfig extends Pick<BaseConfig, 'identityClaimFilter'> {
    */
   organization?: string;
   routes: {
+    callback: string;
     login: string;
   };
 }
diff --git a/src/frontend/use-user.tsx b/src/frontend/use-user.tsx
index 29f721aa..a55cb2e3 100644
--- a/src/frontend/use-user.tsx
+++ b/src/frontend/use-user.tsx
@@ -45,8 +45,8 @@ export type UserContext = {
 export class RequestError extends Error {
   public status: number;
 
-  /* istanbul ignore next */
   constructor(status: number) {
+    /* c8 ignore next */
     super();
     this.status = status;
     Object.setPrototypeOf(this, RequestError.prototype);
diff --git a/src/handlers/auth.ts b/src/handlers/auth.ts
index b3dd54b4..f48ca787 100644
--- a/src/handlers/auth.ts
+++ b/src/handlers/auth.ts
@@ -66,17 +66,16 @@ export type HandleAuth = (userHandlers?: Partial<Handlers>) => NextApiHandler;
 /**
  * @ignore
  */
-const wrapErrorHandling = (fn: NextApiHandler): NextApiHandler => async (
-  req: NextApiRequest,
-  res: NextApiResponse
-): Promise<void> => {
-  try {
-    await fn(req, res);
-  } catch (error) {
-    console.error(error);
-    res.status(error.status || 500).end(error.message);
-  }
-};
+const wrapErrorHandling =
+  (fn: NextApiHandler): NextApiHandler =>
+  async (req: NextApiRequest, res: NextApiResponse): Promise<void> => {
+    try {
+      await fn(req, res);
+    } catch (error) {
+      console.error(error);
+      res.status(error.status || 500).end(error.message);
+    }
+  };
 
 /**
  * @ignore
diff --git a/src/handlers/callback.ts b/src/handlers/callback.ts
index 3c8339bb..570a4cfa 100644
--- a/src/handlers/callback.ts
+++ b/src/handlers/callback.ts
@@ -108,26 +108,23 @@ export type HandleCallback = (req: NextApiRequest, res: NextApiResponse, options
 /**
  * @ignore
  */
-const idTokenValidator = (afterCallback?: AfterCallback, organization?: string): AfterCallback => (
-  req,
-  res,
-  session,
-  state
-) => {
-  if (organization) {
-    assert(session.user.org_id, 'Organization Id (org_id) claim must be a string present in the ID token');
-    assert.equal(
-      session.user.org_id,
-      organization,
-      `Organization Id (org_id) claim value mismatch in the ID token; ` +
-        `expected "${organization}", found "${session.user.org_id}"`
-    );
-  }
-  if (afterCallback) {
-    return afterCallback(req, res, session, state);
-  }
-  return session;
-};
+const idTokenValidator =
+  (afterCallback?: AfterCallback, organization?: string): AfterCallback =>
+  (req, res, session, state) => {
+    if (organization) {
+      assert(session.user.org_id, 'Organization Id (org_id) claim must be a string present in the ID token');
+      assert.equal(
+        session.user.org_id,
+        organization,
+        `Organization Id (org_id) claim value mismatch in the ID token; ` +
+          `expected "${organization}", found "${session.user.org_id}"`
+      );
+    }
+    if (afterCallback) {
+      return afterCallback(req, res, session, state);
+    }
+    return session;
+  };
 
 /**
  * @ignore
diff --git a/src/helpers/with-middleware-auth-required.ts b/src/helpers/with-middleware-auth-required.ts
new file mode 100644
index 00000000..cf1efec3
--- /dev/null
+++ b/src/helpers/with-middleware-auth-required.ts
@@ -0,0 +1,88 @@
+import { NextMiddleware, NextRequest, NextResponse } from 'next/server';
+import { SessionCache } from '../session';
+
+/**
+ * Protect your pages with Next.js Middleware. For example:
+ *
+ * To protect all your routes:
+ *
+ * ```js
+ * // middleware.js
+ * import { withMiddlewareAuthRequired } from '@auth0/nextjs-auth0/middleware';
+ *
+ * export default withMiddlewareAuthRequired();
+ * ```
+ *
+ * To protect specific routes:
+ *
+ * ```js
+ * // middleware.js
+ * import { withMiddlewareAuthRequired } from '@auth0/nextjs-auth0/middleware';
+ *
+ * export default withMiddlewareAuthRequired();
+ *
+ * export const config = {
+ *   matcher: '/about/:path*',
+ * };
+ * ```
+ * For more info see: https://nextjs.org/docs/advanced-features/middleware#matching-paths
+ *
+ * To run custom middleware for authenticated users:
+ *
+ * ```js
+ * // middleware.js
+ * import { withMiddlewareAuthRequired, getSession } from '@auth0/nextjs-auth0/middleware';
+ *
+ * export default withMiddlewareAuthRequired(async function middleware(req) {
+ *   const res = NextResponse.next();
+ *   const user = await getSession(req, res);
+ *   res.cookies.set('hl', user.language);
+ *   return res;
+ * });
+ * ```
+ *
+ * @category Server
+ */
+export type WithMiddlewareAuthRequired = (middleware?: NextMiddleware) => NextMiddleware;
+
+/**
+ * @ignore
+ */
+export default function withMiddlewareAuthRequiredFactory(
+  { login, callback }: { login: string; callback: string },
+  getSessionCache: () => SessionCache<NextRequest, NextResponse>
+): WithMiddlewareAuthRequired {
+  return function withMiddlewareAuthRequired(middleware?): NextMiddleware {
+    return async function wrappedMiddleware(...args) {
+      const [req] = args;
+      const { pathname, origin } = req.nextUrl;
+      const ignorePaths = [login, callback, '/_next', '/favicon.ico'];
+      if (ignorePaths.some((p) => pathname.startsWith(p))) {
+        return;
+      }
+
+      const sessionCache = getSessionCache();
+
+      const authRes = NextResponse.next();
+      const session = await sessionCache.get(req, authRes);
+      if (!session?.user) {
+        return NextResponse.redirect(
+          new URL(`${login}?returnTo=${encodeURIComponent(req.nextUrl.toString())}`, origin)
+        );
+      }
+      const res = await (middleware && middleware(...args));
+
+      if (res) {
+        const headers = new Headers(res.headers);
+        const cookies = headers.get('set-cookie')?.split(', ') || [];
+        const authCookies = authRes.headers.get('set-cookie')?.split(', ') || [];
+        if (cookies.length || authCookies.length) {
+          headers.set('set-cookie', [...authCookies, ...cookies].join(', '));
+        }
+        return NextResponse.next({ ...res, headers });
+      } else {
+        return authRes;
+      }
+    };
+  };
+}
diff --git a/src/index.ts b/src/index.ts
index 7809ce86..1498df31 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,4 +1,5 @@
 import {
+  NodeCookies as Cookies,
   CookieStore,
   TransientStore,
   clientFactory,
@@ -68,7 +69,7 @@ export const _initAuth = (params?: ConfigParameters): SignInWithAuth0 & { sessio
   // Init base layer (with base config)
   const getClient = clientFactory(baseConfig, { name: 'nextjs-auth0', version });
   const transientStore = new TransientStore(baseConfig);
-  const cookieStore = new CookieStore(baseConfig);
+  const cookieStore = new CookieStore(baseConfig, Cookies);
   const sessionCache = new SessionCache(baseConfig, cookieStore);
   const baseHandleLogin = baseLoginHandler(baseConfig, getClient, transientStore);
   const baseHandleLogout = baseLogoutHandler(baseConfig, getClient, sessionCache);
@@ -102,7 +103,7 @@ export const _initAuth = (params?: ConfigParameters): SignInWithAuth0 & { sessio
 };
 
 export const initAuth0: InitAuth0 = (params) => {
-  const { sessionCache, ...publicApi } = _initAuth(params);
+  const { sessionCache, ...publicApi } = _initAuth(params); // eslint-disable-line @typescript-eslint/no-unused-vars
   return publicApi;
 };
 
diff --git a/src/middleware.ts b/src/middleware.ts
new file mode 100644
index 00000000..21ea28c7
--- /dev/null
+++ b/src/middleware.ts
@@ -0,0 +1,48 @@
+import { NextMiddleware, NextRequest, NextResponse } from 'next/server';
+import { default as CookieStore } from './auth0-session/cookie-store';
+import MiddlewareCookies from './utils/middleware-cookies';
+import { SessionCache, Session } from './session/';
+import {
+  WithMiddlewareAuthRequired,
+  default as withMiddlewareAuthRequiredFactory
+} from './helpers/with-middleware-auth-required';
+import { getConfig, ConfigParameters } from './config';
+
+export type Instance = { withMiddlewareAuthRequired: WithMiddlewareAuthRequired; getSession: GetSession };
+
+export type GetSession = (req: NextRequest, res: NextResponse) => Promise<Session | null | undefined>;
+
+export type InitAuth0 = (params?: ConfigParameters) => Instance;
+
+export { WithMiddlewareAuthRequired };
+
+let instance: Instance;
+
+function getInstance(params?: ConfigParameters): Instance {
+  if (instance) {
+    return instance;
+  }
+  instance = initAuth(params);
+  return instance;
+}
+
+export const initAuth: InitAuth0 = (params?) => {
+  const { baseConfig, nextConfig } = getConfig(params);
+
+  // Init base layer (with base config)
+  const cookieStore = new CookieStore<NextRequest, NextResponse>(baseConfig, MiddlewareCookies);
+  const sessionCache = new SessionCache(baseConfig, cookieStore);
+
+  // Init Next layer (with next config)
+  const getSession: GetSession = (req, res) => sessionCache.get(req, res);
+  const withMiddlewareAuthRequired = withMiddlewareAuthRequiredFactory(nextConfig.routes, () => sessionCache);
+
+  return {
+    getSession,
+    withMiddlewareAuthRequired
+  };
+};
+
+export const getSession: GetSession = (...args) => getInstance().getSession(...args);
+export const withMiddlewareAuthRequired: WithMiddlewareAuthRequired = (middleware?: NextMiddleware) =>
+  getInstance().withMiddlewareAuthRequired(middleware);
diff --git a/src/session/cache.ts b/src/session/cache.ts
index 6cc8a69f..291a81d8 100644
--- a/src/session/cache.ts
+++ b/src/session/cache.ts
@@ -1,22 +1,23 @@
 import { IncomingMessage, ServerResponse } from 'http';
 import { NextApiRequest, NextApiResponse } from 'next';
-import { TokenSet } from 'openid-client';
+import type { TokenSet } from 'openid-client';
 import { Config, SessionCache as ISessionCache, CookieStore } from '../auth0-session';
 import Session, { fromJson, fromTokenSet } from './session';
 
-type NextApiOrPageRequest = IncomingMessage | NextApiRequest;
-type NextApiOrPageResponse = ServerResponse | NextApiResponse;
+export default class SessionCache<
+  Req extends object = IncomingMessage | NextApiRequest, // eslint-disable-line @typescript-eslint/ban-types
+  Res extends object = ServerResponse | NextApiResponse // eslint-disable-line @typescript-eslint/ban-types
+> implements ISessionCache<Req, Res, Session>
+{
+  private cache: WeakMap<Req, Session | null>;
+  private iatCache: WeakMap<Req, number | undefined>;
 
-export default class SessionCache implements ISessionCache {
-  private cache: WeakMap<NextApiOrPageRequest, Session | null>;
-  private iatCache: WeakMap<NextApiOrPageRequest, number | undefined>;
-
-  constructor(private config: Config, private cookieStore: CookieStore) {
+  constructor(private config: Config, private cookieStore: CookieStore<Req, Res>) {
     this.cache = new WeakMap();
     this.iatCache = new WeakMap();
   }
 
-  async init(req: NextApiOrPageRequest, res: NextApiOrPageResponse, autoSave = true): Promise<void> {
+  private async init(req: Req, res: Res, autoSave = true): Promise<void> {
     if (!this.cache.has(req)) {
       const [json, iat] = await this.cookieStore.read(req);
       this.iatCache.set(req, iat);
@@ -27,40 +28,40 @@ export default class SessionCache implements ISessionCache {
     }
   }
 
-  async save(req: NextApiOrPageRequest, res: NextApiOrPageResponse): Promise<void> {
+  async save(req: Req, res: Res): Promise<void> {
     await this.cookieStore.save(req, res, this.cache.get(req), this.iatCache.get(req));
   }
 
-  async create(req: NextApiOrPageRequest, res: NextApiOrPageResponse, session: Session): Promise<void> {
+  async create(req: Req, res: Res, session: Session): Promise<void> {
     this.cache.set(req, session);
     await this.save(req, res);
   }
 
-  async delete(req: NextApiOrPageRequest, res: NextApiOrPageResponse): Promise<void> {
+  async delete(req: Req, res: Res): Promise<void> {
     await this.init(req, res, false);
     this.cache.set(req, null);
     await this.save(req, res);
   }
 
-  async isAuthenticated(req: NextApiOrPageRequest, res: NextApiOrPageResponse): Promise<boolean> {
+  async isAuthenticated(req: Req, res: Res): Promise<boolean> {
     await this.init(req, res);
     const session = this.cache.get(req);
     return !!session?.user;
   }
 
-  async getIdToken(req: NextApiOrPageRequest, res: NextApiOrPageResponse): Promise<string | undefined> {
+  async getIdToken(req: Req, res: Res): Promise<string | undefined> {
     await this.init(req, res);
     const session = this.cache.get(req);
     return session?.idToken;
   }
 
-  async set(req: NextApiOrPageRequest, res: NextApiOrPageResponse, session: Session | null): Promise<void> {
+  async set(req: Req, res: Res, session: Session | null): Promise<void> {
     await this.init(req, res, false);
     this.cache.set(req, session);
     await this.save(req, res);
   }
 
-  async get(req: NextApiOrPageRequest, res: NextApiOrPageResponse): Promise<Session | null | undefined> {
+  async get(req: Req, res: Res): Promise<Session | null | undefined> {
     await this.init(req, res);
     return this.cache.get(req);
   }
diff --git a/src/session/get-session.ts b/src/session/get-session.ts
index f119ee7b..b813879b 100644
--- a/src/session/get-session.ts
+++ b/src/session/get-session.ts
@@ -1,6 +1,7 @@
 import { IncomingMessage, ServerResponse } from 'http';
 import { NextApiRequest, NextApiResponse } from 'next';
 import { SessionCache, Session } from '../session';
+import { assertReqRes } from '../utils/assert';
 
 /**
  * Get the user's session from the request.
@@ -17,6 +18,7 @@ export type GetSession = (
  */
 export default function sessionFactory(sessionCache: SessionCache): GetSession {
   return (req, res) => {
+    assertReqRes(req, res);
     return sessionCache.get(req, res);
   };
 }
diff --git a/src/session/session.ts b/src/session/session.ts
index c23f1fd6..54f25029 100644
--- a/src/session/session.ts
+++ b/src/session/session.ts
@@ -1,4 +1,4 @@
-import { TokenSet } from 'openid-client';
+import type { TokenSet } from 'openid-client';
 import { Config } from '../auth0-session';
 import { NextConfig } from '../config';
 
diff --git a/src/session/update-user.ts b/src/session/update-user.ts
index b8a06558..37e3b44f 100644
--- a/src/session/update-user.ts
+++ b/src/session/update-user.ts
@@ -1,6 +1,7 @@
 import { IncomingMessage, ServerResponse } from 'http';
 import { NextApiRequest, NextApiResponse } from 'next';
 import { Claims, SessionCache } from '../session';
+import { assertReqRes } from '../utils/assert';
 
 /**
  * Update the session's user object. The provided user object will replace `session.user`.
@@ -33,7 +34,7 @@ export type UpdateUser = (
  */
 export default function updateUserFactory(sessionCache: SessionCache): UpdateUser {
   return async (req, res, user) => {
-    await sessionCache.init(req, res, false);
+    assertReqRes(req, res);
     const session = await sessionCache.get(req, res);
     if (!session || !user) {
       return;
diff --git a/src/utils/assert.ts b/src/utils/assert.ts
index ae6114a0..a1884830 100644
--- a/src/utils/assert.ts
+++ b/src/utils/assert.ts
@@ -1,6 +1,6 @@
-import { GetServerSidePropsContext, NextApiRequest, NextApiResponse } from 'next';
+import { GetServerSidePropsContext } from 'next';
 
-export const assertReqRes = (req: NextApiRequest, res: NextApiResponse): void => {
+export const assertReqRes = (req: unknown, res: unknown): void => {
   if (!req) {
     throw new Error('Request is not available');
   }
@@ -10,10 +10,5 @@ export const assertReqRes = (req: NextApiRequest, res: NextApiResponse): void =>
 };
 
 export const assertCtx = ({ req, res }: GetServerSidePropsContext<any>): void => {
-  if (!req) {
-    throw new Error('Request is not available');
-  }
-  if (!res) {
-    throw new Error('Response is not available');
-  }
+  assertReqRes(req, res);
 };
diff --git a/src/utils/errors.ts b/src/utils/errors.ts
index 93c11b3c..ce4d0e8a 100644
--- a/src/utils/errors.ts
+++ b/src/utils/errors.ts
@@ -69,8 +69,8 @@ export abstract class AuthError extends Error {
    */
   public readonly status?: number;
 
-  /* istanbul ignore next */
   constructor(options: AuthErrorOptions) {
+    /* c8 ignore next */
     super(appendCause(options.message, options.cause));
     this.code = options.code;
     this.name = options.name;
@@ -104,8 +104,8 @@ export enum AccessTokenErrorCode {
  * @category Server
  */
 export class AccessTokenError extends AuthError {
-  /* istanbul ignore next */
   constructor(code: AccessTokenErrorCode, message: string) {
+    /* c8 ignore next */
     super({ code: code, message: message, name: 'AccessTokenError' });
 
     // Capturing stack trace, excluding constructor call from it.
@@ -145,10 +145,10 @@ type HandlerErrorOptions = {
  * @category Server
  */
 export class HandlerError extends AuthError {
-  /* istanbul ignore next */
   constructor(options: HandlerErrorOptions) {
     let status: number | undefined;
     if ('status' in options.cause) status = options.cause.status;
+    /* c8 ignore next */
     super({ ...options, status });
   }
 }
@@ -174,14 +174,13 @@ export class HandlerError extends AuthError {
 export class CallbackHandlerError extends HandlerError {
   public static readonly code: string = 'ERR_CALLBACK_HANDLER_FAILURE';
 
-  /* istanbul ignore next */
   constructor(cause: HandlerErrorCause) {
     super({
       code: CallbackHandlerError.code,
       message: 'Callback handler failed.',
       name: 'CallbackHandlerError',
       cause
-    });
+    }); /* c8 ignore next */
     Object.setPrototypeOf(this, CallbackHandlerError.prototype);
   }
 }
@@ -195,14 +194,13 @@ export class CallbackHandlerError extends HandlerError {
 export class LoginHandlerError extends HandlerError {
   public static readonly code: string = 'ERR_LOGIN_HANDLER_FAILURE';
 
-  /* istanbul ignore next */
   constructor(cause: HandlerErrorCause) {
     super({
       code: LoginHandlerError.code,
       message: 'Login handler failed.',
       name: 'LoginHandlerError',
       cause
-    });
+    }); /* c8 ignore next */
     Object.setPrototypeOf(this, LoginHandlerError.prototype);
   }
 }
@@ -216,14 +214,13 @@ export class LoginHandlerError extends HandlerError {
 export class LogoutHandlerError extends HandlerError {
   public static readonly code: string = 'ERR_LOGOUT_HANDLER_FAILURE';
 
-  /* istanbul ignore next */
   constructor(cause: HandlerErrorCause) {
     super({
       code: LogoutHandlerError.code,
       message: 'Logout handler failed.',
       name: 'LogoutHandlerError',
       cause
-    });
+    }); /* c8 ignore next */
     Object.setPrototypeOf(this, LogoutHandlerError.prototype);
   }
 }
@@ -237,14 +234,13 @@ export class LogoutHandlerError extends HandlerError {
 export class ProfileHandlerError extends HandlerError {
   public static readonly code: string = 'ERR_PROFILE_HANDLER_FAILURE';
 
-  /* istanbul ignore next */
   constructor(cause: HandlerErrorCause) {
     super({
       code: ProfileHandlerError.code,
       message: 'Profile handler failed.',
       name: 'ProfileHandlerError',
       cause
-    });
+    }); /* c8 ignore next */
     Object.setPrototypeOf(this, ProfileHandlerError.prototype);
   }
 }
diff --git a/src/utils/middleware-cookies.ts b/src/utils/middleware-cookies.ts
new file mode 100644
index 00000000..c9b28eba
--- /dev/null
+++ b/src/utils/middleware-cookies.ts
@@ -0,0 +1,20 @@
+import { Cookies } from '../auth0-session/utils/cookies';
+import { NextRequest, NextResponse } from 'next/server';
+
+export default class MiddlewareCookies extends Cookies {
+  protected getSetCookieHeader(res: NextResponse): string[] {
+    const value = res.headers.get('set-cookie');
+    return value?.split(', ') || [];
+  }
+
+  protected setSetCookieHeader(res: NextResponse, cookies: string[]): void {
+    res.headers.set('set-cookie', cookies.join(', '));
+  }
+
+  getAll(req: NextRequest): Record<string, string> {
+    return Array.from(req.cookies.keys()).reduce((memo: { [key: string]: string }, key) => {
+      memo[key] = req.cookies.get(key) as string;
+      return memo;
+    }, {});
+  }
+}


Test patch:
diff --git a/cypress/integration/smoke.test.ts b/cypress/integration/smoke.test.ts
index d4f1b7ae..9555da7b 100644
--- a/cypress/integration/smoke.test.ts
+++ b/cypress/integration/smoke.test.ts
@@ -47,6 +47,12 @@ describe('smoke tests', () => {
     cy.get('[data-testid=profile]').contains(EMAIL);
   });
 
+  it('should protect a page with middleware', () => {
+    cy.visit('/profile-mw');
+    cy.url().should('eq', `${Cypress.config().baseUrl}/profile-mw`);
+    cy.get('[data-testid=profile]').contains(EMAIL);
+  });
+
   it('should logout and return to the index page', () => {
     cy.get('[data-testid=logout]').click();
     if (!useAuth0) {
diff --git a/src/helpers/testing.ts b/src/helpers/testing.ts
index cb1a89d8..7c85b9a4 100644
--- a/src/helpers/testing.ts
+++ b/src/helpers/testing.ts
@@ -1,4 +1,4 @@
-import { Config as BaseConfig, CookieStore } from '../auth0-session';
+import { Config as BaseConfig, CookieStore, NodeCookies as Cookies } from '../auth0-session';
 import { Session } from '../session';
 import { GenerateSessionCookieConfig } from '../../testing';
 
@@ -9,7 +9,7 @@ export const generateSessionCookie = async (
   const weekInSeconds = 7 * 24 * 60 * 60;
   const { secret, duration: absoluteDuration = weekInSeconds, ...cookie } = config;
   const cookieStoreConfig = { secret, session: { absoluteDuration, cookie } };
-  const cookieStore = new CookieStore(cookieStoreConfig as BaseConfig);
+  const cookieStore = new CookieStore(cookieStoreConfig as BaseConfig, Cookies);
   const epoch = (Date.now() / 1000) | 0;
   return cookieStore.encrypt(session, { iat: epoch, uat: epoch, exp: epoch + absoluteDuration });
 };
diff --git a/tests/auth0-session/config.test.ts b/tests/auth0-session/config.test.ts
index 41570479..9edbf647 100644
--- a/tests/auth0-session/config.test.ts
+++ b/tests/auth0-session/config.test.ts
@@ -267,7 +267,7 @@ describe('Config', () => {
         ...defaultConfig,
         secret: { key: '__test_session_secret__' } as unknown as string // testing invalid configuration
       })
-    ).toThrow('"secret" must be one of [string, binary, array]');
+    ).toThrow('"secret" must be one of [string, array]');
   });
 
   it('should fail when app session cookie httpOnly is not a boolean', function () {
@@ -327,13 +327,13 @@ describe('Config', () => {
 
   it("shouldn't allow a secret of less than 8 chars", () => {
     expect(() => getConfig({ ...defaultConfig, secret: 'short' })).toThrowError(
-      new TypeError('"secret" does not match any of the allowed types')
+      new TypeError('"secret" length must be at least 8 characters long')
     );
     expect(() => getConfig({ ...defaultConfig, secret: ['short', 'too'] })).toThrowError(
-      new TypeError('"secret[0]" does not match any of the allowed types')
+      new TypeError('"secret[0]" length must be at least 8 characters long')
     );
     expect(() => getConfig({ ...defaultConfig, secret: Buffer.from('short').toString() })).toThrowError(
-      new TypeError('"secret" does not match any of the allowed types')
+      new TypeError('"secret" length must be at least 8 characters long')
     );
   });
 
diff --git a/tests/auth0-session/fixtures/server.ts b/tests/auth0-session/fixtures/server.ts
index 1469bfcb..fce41372 100644
--- a/tests/auth0-session/fixtures/server.ts
+++ b/tests/auth0-session/fixtures/server.ts
@@ -6,6 +6,7 @@ import nock from 'nock';
 import { TokenSet, TokenSetParameters } from 'openid-client';
 import bodyParser from 'body-parser';
 import {
+  NodeCookies as Cookies,
   loginHandler,
   getConfig,
   ConfigParameters,
@@ -59,7 +60,7 @@ const createHandlers = (params: ConfigParameters): Handlers => {
   const config = getConfig(params);
   const getClient = clientFactory(config, { name: 'nextjs-auth0', version });
   const transientStore = new TransientStore(config);
-  const cookieStore = new CookieStore(config);
+  const cookieStore = new CookieStore(config, Cookies);
   const sessionCache = new TestSessionCache(cookieStore);
 
   return {
diff --git a/tests/auth0-session/utils/cookie.test.ts b/tests/auth0-session/utils/cookie.test.ts
index 773c04ac..04b1e1c7 100644
--- a/tests/auth0-session/utils/cookie.test.ts
+++ b/tests/auth0-session/utils/cookie.test.ts
@@ -1,6 +1,6 @@
 import { AddressInfo } from 'net';
 import { createServer, get as getRequest, IncomingMessage, ServerResponse } from 'http';
-import Cookies from '../../../src/auth0-session/utils/cookies';
+import NodeCookies from '../../../src/auth0-session/utils/cookies';
 
 const setup = (): Promise<[IncomingMessage, ServerResponse, Function]> =>
   new Promise((resolve) => {
@@ -25,20 +25,20 @@ describe('cookie', () => {
   it('should get all cookies', async () => {
     const [req, , teardown] = await setup();
     req.headers.cookie = 'foo=bar; bar=baz;';
-    expect(Cookies.getAll(req)).toMatchObject({ foo: 'bar', bar: 'baz' });
+    expect(new NodeCookies().getAll(req)).toMatchObject({ foo: 'bar', bar: 'baz' });
     await teardown();
   });
 
   it('should get a cookie by name', async () => {
     const [req, , teardown] = await setup();
     req.headers.cookie = 'foo=bar; bar=baz;';
-    expect(Cookies.getAll(req)['foo']).toEqual('bar');
+    expect(new NodeCookies().getAll(req)['foo']).toEqual('bar');
     await teardown();
   });
 
   it('should set a cookie', async () => {
     const [, res, teardown] = await setup();
-    const setter = new Cookies();
+    const setter = new NodeCookies();
     setter.set('foo', 'bar');
     setter.commit(res);
     expect(res.getHeader('Set-Cookie')).toEqual(['foo=bar']);
@@ -47,7 +47,7 @@ describe('cookie', () => {
 
   it('should set a cookie with opts', async () => {
     const [, res, teardown] = await setup();
-    const setter = new Cookies();
+    const setter = new NodeCookies();
     setter.set('foo', 'bar', { httpOnly: true, sameSite: 'strict' });
     setter.commit(res);
     expect(res.getHeader('Set-Cookie')).toEqual(['foo=bar; HttpOnly; SameSite=Strict']);
@@ -57,7 +57,7 @@ describe('cookie', () => {
   it('should not overwrite existing set cookie', async () => {
     const [, res, teardown] = await setup();
     res.setHeader('Set-Cookie', 'foo=bar');
-    const setter = new Cookies();
+    const setter = new NodeCookies();
     setter.set('baz', 'qux');
     setter.commit(res);
     expect(res.getHeader('Set-Cookie')).toEqual(['foo=bar', 'baz=qux']);
@@ -67,7 +67,7 @@ describe('cookie', () => {
   it('should override existing cookies that equal name', async () => {
     const [, res, teardown] = await setup();
     res.setHeader('Set-Cookie', ['foo=bar', 'baz=qux']);
-    const setter = new Cookies();
+    const setter = new NodeCookies();
     setter.set('foo', 'qux');
     setter.commit(res, 'foo');
     expect(res.getHeader('Set-Cookie')).toEqual(['baz=qux', 'foo=qux']);
@@ -77,7 +77,7 @@ describe('cookie', () => {
   it('should override existing cookies that match name', async () => {
     const [, res, teardown] = await setup();
     res.setHeader('Set-Cookie', ['foo.1=bar', 'foo.2=baz']);
-    const setter = new Cookies();
+    const setter = new NodeCookies();
     setter.set('foo', 'qux');
     setter.commit(res, 'foo');
     expect(res.getHeader('Set-Cookie')).toEqual(['foo=qux']);
@@ -86,7 +86,7 @@ describe('cookie', () => {
 
   it('should clear cookies', async () => {
     const [, res, teardown] = await setup();
-    const setter = new Cookies();
+    const setter = new NodeCookies();
     setter.clear('foo');
     setter.commit(res);
     expect(res.getHeader('Set-Cookie')).toEqual(['foo=; Max-Age=0']);
diff --git a/tests/helpers/testing.test.ts b/tests/helpers/testing.test.ts
index 944cd0f2..aecd4103 100644
--- a/tests/helpers/testing.test.ts
+++ b/tests/helpers/testing.test.ts
@@ -9,7 +9,10 @@ const weekInSeconds = 7 * 24 * 60 * 60;
 describe('generate-session-cookie', () => {
   test('use the provided secret', async () => {
     await generateSessionCookie({}, { secret: '__test_secret__' });
-    expect(CookieStore).toHaveBeenCalledWith(expect.objectContaining({ secret: '__test_secret__' }));
+    expect(CookieStore).toHaveBeenCalledWith(
+      expect.objectContaining({ secret: '__test_secret__' }),
+      expect.any(Function)
+    );
   });
 
   test('use the default session configuration values', async () => {
@@ -17,7 +20,8 @@ describe('generate-session-cookie', () => {
     expect(CookieStore).toHaveBeenCalledWith(
       expect.objectContaining({
         session: { absoluteDuration: weekInSeconds, cookie: {} }
-      })
+      }),
+      expect.any(Function)
     );
   });
 
@@ -48,7 +52,8 @@ describe('generate-session-cookie', () => {
             sameSite: 'none'
           }
         }
-      })
+      }),
+      expect.any(Function)
     );
   });
 
diff --git a/tests/helpers/with-middleware-auth-required.test.ts b/tests/helpers/with-middleware-auth-required.test.ts
new file mode 100644
index 00000000..f38852ca
--- /dev/null
+++ b/tests/helpers/with-middleware-auth-required.test.ts
@@ -0,0 +1,179 @@
+/**
+ * @jest-environment @edge-runtime/jest-environment
+ */
+import { NextRequest, NextResponse } from 'next/server';
+import { NextFetchEvent } from 'next/dist/server/web/spec-extension/fetch-event';
+import { initAuth } from '../../src/middleware';
+import { withoutApi } from '../fixtures/default-settings';
+import { IdTokenClaims } from 'openid-client';
+import { encryption as deriveKey } from '../../src/auth0-session/utils/hkdf';
+import { defaultConfig } from '../auth0-session/fixtures/helpers';
+import { makeIdToken } from '../auth0-session/fixtures/cert';
+import * as jose from 'jose';
+
+const encrypted = async (claims: Partial<IdTokenClaims> = { sub: '__test_sub__' }): Promise<string> => {
+  const key = await deriveKey(defaultConfig.secret as string);
+  const epochNow = (Date.now() / 1000) | 0;
+  const weekInSeconds = 7 * 24 * 60 * 60;
+  const payload = {
+    user: claims,
+    access_token: '__test_access_token__',
+    token_type: 'Bearer',
+    id_token: await makeIdToken(claims),
+    refresh_token: '__test_access_token__',
+    expires_at: epochNow + weekInSeconds
+  };
+  return new jose.EncryptJWT({ ...payload })
+    .setProtectedHeader({
+      alg: 'dir',
+      enc: 'A256GCM',
+      uat: epochNow,
+      iat: epochNow,
+      exp: epochNow + weekInSeconds
+    })
+    .encrypt(key);
+};
+
+const setup = async ({ url = 'http://example.com', config = withoutApi, user, middleware }: any = {}) => {
+  const mw = initAuth(config).withMiddlewareAuthRequired(middleware);
+  const request = new NextRequest(new URL(url));
+  if (user) {
+    request.cookies.set('appSession', await encrypted({ sub: 'foo' }));
+  }
+  return mw(request, new NextFetchEvent({ request, page: '/' })) as NextResponse;
+};
+
+describe('with-middleware-auth-required', () => {
+  test('require auth on anonymous request', async () => {
+    const res = await setup();
+    expect(res.status).toEqual(307);
+    const redirect = new URL(res.headers.get('location') as string);
+    expect(redirect).toMatchObject({
+      hostname: 'example.com',
+      pathname: '/api/auth/login'
+    });
+    expect(redirect.searchParams.get('returnTo')).toEqual('http://example.com/');
+  });
+
+  test('return to previous url', async () => {
+    const res = await setup({ url: 'http://example.com/foo/bar?baz=hello' });
+    const redirect = new URL(res.headers.get('location') as string);
+    expect(redirect).toMatchObject({
+      hostname: 'example.com',
+      pathname: '/api/auth/login'
+    });
+    expect(redirect.searchParams.get('returnTo')).toEqual('http://example.com/foo/bar?baz=hello');
+  });
+
+  test('should ignore static urls', async () => {
+    const res = await setup({ url: 'http://example.com/_next/style.css' });
+    expect(res).toBeUndefined();
+  });
+
+  test('should ignore default sdk urls', async () => {
+    const res = await setup({ url: 'http://example.com/api/auth/login' });
+    expect(res).toBeUndefined();
+  });
+
+  test('should ignore custom sdk urls', async () => {
+    const res = await setup({
+      url: 'http://example.com/api/custom-login',
+      config: {
+        ...withoutApi,
+        routes: { ...withoutApi.routes, login: '/api/custom-login' }
+      }
+    });
+    expect(res).toBeUndefined();
+  });
+
+  test('should redirect to custom sdk urls', async () => {
+    const res = await setup({
+      url: 'http://example.com/my-page',
+      config: {
+        ...withoutApi,
+        routes: { ...withoutApi.routes, login: '/api/custom-login' }
+      }
+    });
+    const redirect = new URL(res.headers.get('location') as string);
+    expect(redirect).toMatchObject({
+      hostname: 'example.com',
+      pathname: '/api/custom-login'
+    });
+  });
+
+  test('should not redirect to 3rd party domain', async () => {
+    const res = await setup({ url: 'http://example.com//evil.com' });
+    const redirect = new URL(res.headers.get('location') as string);
+    expect(redirect).toMatchObject({
+      hostname: 'example.com'
+    });
+  });
+
+  test('should not run custom middleware for unauthenticated users', async () => {
+    const middleware = jest.fn();
+    await setup({ middleware });
+    expect(middleware).not.toHaveBeenCalled();
+  });
+
+  test('should allow authenticated sessions to pass', async () => {
+    const res = await setup({ user: { name: 'dave' } });
+    expect(res.status).toEqual(200);
+  });
+
+  test('should run custom middleware for authenticated users', async () => {
+    const middleware = jest.fn();
+    await setup({ middleware, user: { name: 'dave' } });
+    expect(middleware).toHaveBeenCalled();
+  });
+
+  test('should set a session cookie if session is rolling', async () => {
+    const res = await setup({ user: { name: 'dave' } });
+    expect(res.status).toEqual(200);
+    expect(res.headers.get('set-cookie')).toMatch(/^appSession=/);
+  });
+
+  test('should not set a session cookie if session is not rolling', async () => {
+    const res = await setup({ user: { name: 'dave' }, config: { ...withoutApi, session: { rolling: false } } });
+    expect(res.status).toEqual(200);
+    expect(res.headers.get('set-cookie')).toBeNull();
+  });
+
+  test('should set a session cookie and a custom cookie', async () => {
+    const middleware = () => {
+      const res = NextResponse.next();
+      res.cookies.set('foo', 'bar');
+      return res;
+    };
+    const res = await setup({ user: { name: 'dave' }, middleware });
+    expect(res.status).toEqual(200);
+    expect(res.headers.get('set-cookie')).toMatch(/^appSession=.+, foo=bar;/);
+  });
+
+  test('should set just a custom cookie when session is not rolling', async () => {
+    const middleware = () => {
+      const res = NextResponse.next();
+      res.cookies.set('foo', 'bar');
+      return res;
+    };
+    const res = await setup({
+      user: { name: 'dave' },
+      config: { ...withoutApi, session: { rolling: false } },
+      middleware
+    });
+    expect(res.status).toEqual(200);
+    expect(res.headers.get('set-cookie')).toEqual('foo=bar; Path=/');
+  });
+
+  test('should not set a custom cookie or session cookie when session is not rolling', async () => {
+    const middleware = () => {
+      return NextResponse.next();
+    };
+    const res = await setup({
+      user: { name: 'dave' },
+      config: { ...withoutApi, session: { rolling: false } },
+      middleware
+    });
+    expect(res.status).toEqual(200);
+    expect(res.headers.get('set-cookie')).toBeNull();
+  });
+});
diff --git a/tests/session/cache.test.ts b/tests/session/cache.test.ts
index bccc3f7c..acf05b42 100644
--- a/tests/session/cache.test.ts
+++ b/tests/session/cache.test.ts
@@ -1,7 +1,7 @@
 import { IncomingMessage, ServerResponse } from 'http';
 import { Socket } from 'net';
 import { mocked } from 'ts-jest/utils';
-import { CookieStore, getConfig } from '../../src/auth0-session';
+import { NodeCookies as Cookies, CookieStore, getConfig } from '../../src/auth0-session';
 import { ConfigParameters, Session, SessionCache } from '../../src';
 import { withoutApi } from '../fixtures/default-settings';
 
@@ -14,7 +14,7 @@ describe('SessionCache', () => {
 
   const setup = (conf: ConfigParameters) => {
     const config = getConfig(conf);
-    cookieStore = mocked(new CookieStore(config));
+    cookieStore = mocked(new CookieStore(config, Cookies));
     cookieStore.save = jest.fn();
     session = new Session({ sub: '__test_user__' });
     session.idToken = '__test_id_token__';
diff --git a/tests/setup.ts b/tests/setup.ts
index 1d1e5fd5..3f6b547e 100644
--- a/tests/setup.ts
+++ b/tests/setup.ts
@@ -1,3 +1,17 @@
+import { Buffer } from 'buffer';
+
+if (typeof TextDecoder !== 'undefined') {
+  // Monkey patch Text Decoder to workaround https://github.com/vercel/edge-runtime/issues/62
+  // This can be removed when https://github.com/vercel/edge-runtime/pull/80 is merged
+  const tmp = TextDecoder.prototype.decode;
+  TextDecoder.prototype.decode = function (input, options) {
+    if (Buffer.isBuffer(input)) {
+      return tmp.call(this, new TextEncoder().encode(input.toString()), options);
+    }
+    return tmp.call(this, input, options);
+  };
+}
+
 beforeEach(() => {
   jest.spyOn(console, 'warn').mockImplementation(() => {
     // no-op
diff --git a/tests/utils/middleware-cookies.test.ts b/tests/utils/middleware-cookies.test.ts
new file mode 100644
index 00000000..dd3ce8ba
--- /dev/null
+++ b/tests/utils/middleware-cookies.test.ts
@@ -0,0 +1,72 @@
+/**
+ * @jest-environment @edge-runtime/jest-environment
+ */
+import MiddlewareCookies from '../../src/utils/middleware-cookies';
+import { NextRequest, NextResponse } from 'next/server';
+
+const setup = (reqInit?: RequestInit): [NextRequest, NextResponse] => {
+  return [new NextRequest(new URL('http://example.com'), reqInit), NextResponse.next()];
+};
+
+describe('cookie', () => {
+  it('should get all cookies', async () => {
+    const [req] = setup({ headers: { cookie: 'foo=bar; bar=baz;' } });
+    expect(new MiddlewareCookies().getAll(req)).toMatchObject({ foo: 'bar', bar: 'baz' });
+  });
+
+  it('should get a cookie by name', async () => {
+    const [req] = setup({ headers: { cookie: 'foo=bar; bar=baz;' } });
+    expect(new MiddlewareCookies().getAll(req)['foo']).toEqual('bar');
+  });
+
+  it('should set a cookie', async () => {
+    const [, res] = setup();
+    const setter = new MiddlewareCookies();
+    setter.set('foo', 'bar');
+    setter.commit(res);
+    expect(res.headers.get('set-cookie')).toEqual('foo=bar');
+  });
+
+  it('should set a cookie with opts', async () => {
+    const [, res] = setup();
+    const setter = new MiddlewareCookies();
+    setter.set('foo', 'bar', { httpOnly: true, sameSite: 'strict' });
+    setter.commit(res);
+    expect(res.headers.get('set-cookie')).toEqual('foo=bar; HttpOnly; SameSite=Strict');
+  });
+
+  it('should not overwrite existing set cookie', async () => {
+    const [, res] = setup();
+    res.headers.set('set-cookie', 'foo=bar');
+    const setter = new MiddlewareCookies();
+    setter.set('baz', 'qux');
+    setter.commit(res);
+    expect(res.headers.get('set-cookie')).toEqual(['foo=bar', 'baz=qux'].join(', '));
+  });
+
+  it('should override existing cookies that equal name', async () => {
+    const [, res] = setup();
+    res.headers.set('set-cookie', ['foo=bar', 'baz=qux'].join(', '));
+    const setter = new MiddlewareCookies();
+    setter.set('foo', 'qux');
+    setter.commit(res, 'foo');
+    expect(res.headers.get('set-cookie')).toEqual(['baz=qux', 'foo=qux'].join(', '));
+  });
+
+  it('should override existing cookies that match name', async () => {
+    const [, res] = setup();
+    res.headers.set('set-cookie', ['foo.1=bar', 'foo.2=baz'].join(', '));
+    const setter = new MiddlewareCookies();
+    setter.set('foo', 'qux');
+    setter.commit(res, 'foo');
+    expect(res.headers.get('set-cookie')).toEqual('foo=qux');
+  });
+
+  it('should clear cookies', async () => {
+    const [, res] = setup();
+    const setter = new MiddlewareCookies();
+    setter.clear('foo');
+    setter.commit(res);
+    expect(res.headers.get('set-cookie')).toEqual('foo=; Max-Age=0');
+  });
+});