diff --git a/.env.sample b/.env.sample
new file mode 100644
index 0000000..209ce0b
--- /dev/null
+++ b/.env.sample
@@ -0,0 +1,3 @@
+MSSQL='Server=.database.windows.net;Initial Catalog=;Persist Security Info=False;User ID=session_recommender_app;Password=unEno!h5!&*KP420xds&@P901afb$^M;MultipleActiveResultSets=False;Encrypt=True;Connection Timeout=30;'
+OPENAI.URL='https://.openai.azure.com'
+OPENAI.KEY=''
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..8efbe82
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,13 @@
+# Thanks to: https://rehansaeed.com/gitattributes-best-practices/
+
+# Set default behavior to automatically normalize line endings.
+* text=auto
+
+# Force batch scripts to always use CRLF line endings so that if a repo is accessed
+# in Windows via a file share from Linux, the scripts will work.
+*.{cmd,[cC][mM][dD]} text eol=crlf
+*.{bat,[bB][aA][tT]} text eol=crlf
+
+# Force bash scripts to always use LF line endings so that if a repo is accessed
+# in Unix via a file share from Windows, the scripts will work.
+*.sh text eol=lf
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 8a30d25..e21ec49 100644
--- a/.gitignore
+++ b/.gitignore
@@ -396,3 +396,9 @@ FodyWeavers.xsd
# JetBrains Rider
*.sln.iml
+
+# Custom
+.env
+azuredeploy.parameters.json
+*.zip
+.azure/
diff --git a/.nvmrc b/.nvmrc
new file mode 100644
index 0000000..2edeafb
--- /dev/null
+++ b/.nvmrc
@@ -0,0 +1 @@
+20
\ No newline at end of file
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
new file mode 100644
index 0000000..bb76300
--- /dev/null
+++ b/.vscode/extensions.json
@@ -0,0 +1,6 @@
+{
+ "recommendations": [
+ "ms-azuretools.vscode-azurefunctions",
+ "ms-dotnettools.csharp"
+ ]
+}
\ No newline at end of file
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 0000000..a778a15
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,25 @@
+{
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "Attach to .NET Functions",
+ "type": "coreclr",
+ "request": "attach",
+ "processId": "${command:azureFunctions.pickProcess}"
+ },
+ {
+ "name": "Run web app",
+ "type": "node",
+ "request": "launch",
+ "cwd": "${workspaceFolder}",
+ "runtimeExecutable": "swa",
+ "runtimeArgs": ["start"],
+ "presentation": {
+ "hidden": false,
+ "group": "Frontend",
+ "order": 1
+ },
+ "preLaunchTask": "npm: install"
+ }
+ ]
+}
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..4ff618a
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,7 @@
+{
+ "azureFunctions.deploySubpath": "api/bin/Release/net8.0/publish",
+ "azureFunctions.projectLanguage": "C#",
+ "azureFunctions.projectRuntime": "~4",
+ "debug.internalConsoleOptions": "neverOpen",
+ "azureFunctions.preDeployTask": "publish (functions)"
+}
\ No newline at end of file
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
new file mode 100644
index 0000000..370f7e1
--- /dev/null
+++ b/.vscode/tasks.json
@@ -0,0 +1,89 @@
+{
+ "version": "2.0.0",
+ "tasks": [
+ {
+ "label": "clean (functions)",
+ "command": "dotnet",
+ "args": [
+ "clean",
+ "/property:GenerateFullPaths=true",
+ "/consoleloggerparameters:NoSummary"
+ ],
+ "type": "process",
+ "problemMatcher": "$msCompile",
+ "options": {
+ "cwd": "${workspaceFolder}/api"
+ }
+ },
+ {
+ "label": "build (functions)",
+ "command": "dotnet",
+ "args": [
+ "build",
+ "/property:GenerateFullPaths=true",
+ "/consoleloggerparameters:NoSummary"
+ ],
+ "type": "process",
+ "dependsOn": "clean (functions)",
+ "group": {
+ "kind": "build",
+ "isDefault": true
+ },
+ "problemMatcher": "$msCompile",
+ "options": {
+ "cwd": "${workspaceFolder}/api"
+ }
+ },
+ {
+ "label": "clean release (functions)",
+ "command": "dotnet",
+ "args": [
+ "clean",
+ "--configuration",
+ "Release",
+ "/property:GenerateFullPaths=true",
+ "/consoleloggerparameters:NoSummary"
+ ],
+ "type": "process",
+ "problemMatcher": "$msCompile",
+ "options": {
+ "cwd": "${workspaceFolder}/api"
+ }
+ },
+ {
+ "label": "publish (functions)",
+ "command": "dotnet",
+ "args": [
+ "publish",
+ "--configuration",
+ "Release",
+ "/property:GenerateFullPaths=true",
+ "/consoleloggerparameters:NoSummary"
+ ],
+ "type": "process",
+ "dependsOn": "clean release (functions)",
+ "problemMatcher": "$msCompile",
+ "options": {
+ "cwd": "${workspaceFolder}/api"
+ }
+ },
+ {
+ "type": "func",
+ "dependsOn": "build (functions)",
+ "options": {
+ "cwd": "${workspaceFolder}/api/bin/Debug/net8.0"
+ },
+ "command": "host start",
+ "isBackground": true,
+ "problemMatcher": "$func-dotnet-watch"
+ },
+ {
+ "type": "npm",
+ "options": {
+ "cwd": "${workspaceFolder}/client"
+ },
+ "script": "install",
+ "label": "npm: install"
+ }
+ ]
+}
diff --git a/README.md b/README.md
index 4fcc945..46433b3 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,168 @@
-Coming Soon!
+---
+page_type: sample
+languages:
+- azdeveloper
+- csharp
+- sql
+- tsql
+- javascript
+- html
+- bicep
+products:
+- azure-functions
+- azure-sql-database
+- static-web-apps
+- sql-server
+- azure-sql-managed-instance
+- azure-sqlserver-vm
+- dotnet
+- azure-openai
+urlFragment: azure-sql-db-session-recommender
+name: Session Recommender using Azure SQL DB, Open AI and Vector Search
+description: Build a session recommender using Jamstack and Event-Driven architecture, using Azure SQL DB to store and search vectors embeddings generated using OpenAI
+---
+
-In the meantime take a look at v1 of this project:
+# Session Assistant Sample - Retrieveal Augmented Generation with Azure SQL DB and OpenAI
-- https://sessionfinder.dotnetconf.net/
-- https://github.com/Azure-Samples/azure-sql-db-session-recommender
+This repository is a evoution of the [Session Recommender](https://github.com/azure-samples/azure-sql-db-session-recommender) sample. In addition to vector search, also Retrival Augmented Generation (RAG) is used to generate the response to the user query. If you are completely new to this topic, you may want to start there, and then come back here.
+
+
+
+A session recommender built using
+
+- [Azure Static Web Apps](https://learn.microsoft.com/en-us/azure/static-web-apps/overview)
+- [Azure OpenAI](https://learn.microsoft.com/en-us/azure/ai-services/openai/)
+- [Azure Functions](https://learn.microsoft.com/en-us/azure/azure-functions/functions-overview?pivots=programming-language-csharp)
+- [Azure SQL Database](https://www.sqlservercentral.com/articles/the-sql-developer-experience-beyond-rdbms)
+- [Data API builder](https://aka.ms/dab)
+
+For more details on the solution check also the following articles:
+
+- [How I built a session recommender in 1 hour using Open AI](https://dev.to/azure/how-i-built-a-session-recommender-in-1-hour-using-open-ai-5419)
+- [Vector Similarity Search with Azure SQL database and OpenAI](https://devblogs.microsoft.com/azure-sql/vector-similarity-search-with-azure-sql-database-and-openai/)
+
+# Deploy the sample using the Azure Developer CLI (azd) template
+
+The Azure Developer CLI (`azd`) is a developer-centric command-line interface (CLI) tool for creating Azure applications.
+
+## Prerequisites
+
+- Install [AZD CLI](https://learn.microsoft.com/azure/developer/azure-developer-cli/install-azd).
+- Install [.NET SDK](https://dotnet.microsoft.com/download).
+- Install [Node.js](https://nodejs.org/download/).
+- Install [SWA CLI](https://azure.github.io/static-web-apps-cli/docs/use/install#installing-the-cli).
+
+## Install AZD CLI
+
+You need to install it before running and deploying with the Azure Developer CLI.
+
+### Windows
+
+```powershell
+powershell -ex AllSigned -c "Invoke-RestMethod 'https://aka.ms/install-azd.ps1' | Invoke-Expression"
+```
+
+### Linux/MacOS
+
+```bash
+curl -fsSL https://aka.ms/install-azd.sh | bash
+```
+
+After logging in with the following command, you will be able to use azd cli to quickly provision and deploy the application.
+
+## Authenticate with Azure
+
+Make sure AZD CLI can access Azure resources. You can use the following command to log in to Azure:
+
+```bash
+azd auth login
+```
+
+## Initialize the template
+
+Then, execute the `azd init` command to initialize the environment (You do not need to run this command if you already have the code or have opened this in a Codespace or DevContainer).
+
+```bash
+azd init -t Azure-Samples/azure-sql-db-session-recommender-v2
+```
+
+Enter an environment name.
+
+## Deploy the sample
+
+Run `azd up` to provision all the resources to Azure and deploy the code to those resources.
+
+```bash
+azd up
+```
+
+Select your desired `subscription` and `location`. Then choose a resource group or create a new resource group. Wait a moment for the resource deployment to complete, click the Website endpoint and you will see the web app page.
+
+**Note**: Make sure to pick a region where all services are available like, for example, *West Europe* or *East US 2*
+
+## GitHub Actions
+
+Using the Azure Developer CLI, you can setup your pipelines, monitor your application, test and debug locally.
+
+```bash
+azd pipeline config
+```
+
+## Test the solution
+
+Add a new row to the `Sessions` table using the following SQL statement (you can use tools like [Azure Data Studio](https://learn.microsoft.com/en-us/azure-data-studio/quickstart-sql-database) or [SQL Server Management Studio](https://learn.microsoft.com/en-us/azure/azure-sql/database/connect-query-ssms?view=azuresql) to connect to the database. No need to install them if you don't want. In that case you can use the [SQL Editor in the Azure Portal](https://learn.microsoft.com/en-us/azure/azure-sql/database/connect-query-portal?view=azuresql)):
+
+```sql
+insert into web.sessions
+ (title, abstract, external_id, start_time_PST, end_time_PST, require_embeddings_update)
+values
+ (
+ 'Building a session recommender using OpenAI and Azure SQL',
+ 'In this fun and demo-driven session you’ll learn how to integrate Azure SQL with OpenAI to generate text embeddings, store them in the database, index them and calculate cosine distance to build a session recommender. And once that is done, you’ll publish it as a REST and GraphQL API to be consumed by a modern JavaScript frontend. Sounds pretty cool, uh? Well, it is!',
+ 'S1',
+ '2024-03-10 10:00:00',
+ '2024-03-10 11:00:00',
+ 1
+ )
+```
+
+immediately the deployed Azure Function will get executed in response to the `INSERT` statement. The Azure Function will call the OpenAI service to generate the text embedding for the session title and abstract, and then store the embedding in the database, specifically in the `web.sessions_embeddings` table.
+
+```sql
+select * from web.sessions_embeddings
+```
+
+You can now open the URL associated with the created Static Web App to see the session recommender in action. You can get the URL from the Static Web App overview page in the Azure portal.
+
+
+
+## Run the solution locally
+
+The whole solution can be executed locally, using [Static Web App CLI](https://github.com/Azure/static-web-apps-cli) and [Azure Function CLI](https://learn.microsoft.com/en-us/azure/azure-functions/functions-run-local?tabs=windows%2Cisolated-process%2Cnode-v4%2Cpython-v2%2Chttp-trigger%2Ccontainer-apps&pivots=programming-language-csharp).
+
+Install the required node packages needed by the fronted:
+
+```bash
+cd client
+npm install
+```
+
+once finished, create a `./func/local.settings.json` and `.env` starting from provided samples files, and fill out the settings using the correct values for your environment.
+
+From the sample root folder run:
+
+```bash
+swa start ./client --api-location ./func --data-api-location ./swa-db-connections
+```
+
+## Fluent UI
+
+The solution uses Fluent UI for the UI components. The Fluent UI is a collection of UX frameworks from Microsoft that provides a consistent design language for web, mobile, and desktop applications. More details about Fluent UI can be found at the following links:
+
+- https://github.com/microsoft/fluentui
+- https://react.fluentui.dev/
+
+## Credits
+
+Thanks a lot to [Aaron Powell](https://www.aaron-powell.com/) for having helped in building the RAG sample, doing a complete UI revamp using the Fluent UI and for the implementaiton of the `ask` endpoint.
\ No newline at end of file
diff --git a/azure.yaml b/azure.yaml
new file mode 100644
index 0000000..b03c92c
--- /dev/null
+++ b/azure.yaml
@@ -0,0 +1,15 @@
+# yaml-language-server: $schema=https://raw.githubusercontent.com/Azure/azure-dev/main/schemas/v1.0/azure.yaml.json
+
+name: azure-sql-db-session-recommender-v2
+metadata:
+ template: azure-sql-db-session-recommender-v2
+services:
+ web:
+ project: ./client
+ language: js
+ host: staticwebapp
+ dist: dist
+ functionapp:
+ project: ./func
+ language: dotnet
+ host: function
\ No newline at end of file
diff --git a/client/.eslintrc.cjs b/client/.eslintrc.cjs
new file mode 100644
index 0000000..4dcb439
--- /dev/null
+++ b/client/.eslintrc.cjs
@@ -0,0 +1,20 @@
+module.exports = {
+ root: true,
+ env: { browser: true, es2020: true },
+ extends: [
+ 'eslint:recommended',
+ 'plugin:react/recommended',
+ 'plugin:react/jsx-runtime',
+ 'plugin:react-hooks/recommended',
+ ],
+ ignorePatterns: ['dist', '.eslintrc.cjs'],
+ parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
+ settings: { react: { version: '18.2' } },
+ plugins: ['react-refresh'],
+ rules: {
+ 'react-refresh/only-export-components': [
+ 'warn',
+ { allowConstantExport: true },
+ ],
+ },
+}
diff --git a/client/.gitignore b/client/.gitignore
new file mode 100644
index 0000000..a547bf3
--- /dev/null
+++ b/client/.gitignore
@@ -0,0 +1,24 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist
+dist-ssr
+*.local
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
diff --git a/client/index.html b/client/index.html
new file mode 100644
index 0000000..f0fa470
--- /dev/null
+++ b/client/index.html
@@ -0,0 +1,17 @@
+
+
+
+
+
+ Conference AI Assistant
+
+
+
+
+
+
+
+
+
+
+
diff --git a/client/package-lock.json b/client/package-lock.json
new file mode 100644
index 0000000..dd95fcd
--- /dev/null
+++ b/client/package-lock.json
@@ -0,0 +1,7054 @@
+{
+ "name": "client",
+ "version": "0.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "client",
+ "version": "0.0.0",
+ "dependencies": {
+ "@fluentui/react": "^8.115.5",
+ "@fluentui/react-components": "^9.38.0",
+ "dayjs": "^1.11.10",
+ "localforage": "^1.10.0",
+ "localstorage-slim": "^2.7.0",
+ "match-sorter": "^6.3.1",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0",
+ "react-markdown": "^9.0.1",
+ "react-router-dom": "^6.16.0",
+ "sort-by": "^1.2.0"
+ },
+ "devDependencies": {
+ "@types/react": "^18.2.15",
+ "@types/react-dom": "^18.2.7",
+ "@typescript-eslint/eslint-plugin": "^6.10.0",
+ "@typescript-eslint/parser": "^6.10.0",
+ "@vitejs/plugin-react": "^4.0.3",
+ "eslint": "^8.45.0",
+ "eslint-plugin-react": "^7.32.2",
+ "eslint-plugin-react-hooks": "^4.6.0",
+ "eslint-plugin-react-refresh": "^0.4.3",
+ "typescript": "^5.2.2",
+ "vite": "^4.4.5"
+ }
+ },
+ "node_modules/@aashutoshrathi/word-wrap": {
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz",
+ "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/@ampproject/remapping": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz",
+ "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.0",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.23.5",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz",
+ "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/highlight": "^7.23.4",
+ "chalk": "^2.4.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/compat-data": {
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.20.tgz",
+ "integrity": "sha512-BQYjKbpXjoXwFW5jGqiizJQQT/aC7pFm9Ok1OWssonuguICi264lbgMzRp2ZMmRSlfkX6DsWDDcsrctK8Rwfiw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core": {
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.0.tgz",
+ "integrity": "sha512-97z/ju/Jy1rZmDxybphrBuI+jtJjFVoz7Mr9yUQVVVi+DNZE333uFQeMOqcCIy1x3WYBIbWftUSLmbNXNT7qFQ==",
+ "dev": true,
+ "dependencies": {
+ "@ampproject/remapping": "^2.2.0",
+ "@babel/code-frame": "^7.22.13",
+ "@babel/generator": "^7.23.0",
+ "@babel/helper-compilation-targets": "^7.22.15",
+ "@babel/helper-module-transforms": "^7.23.0",
+ "@babel/helpers": "^7.23.0",
+ "@babel/parser": "^7.23.0",
+ "@babel/template": "^7.22.15",
+ "@babel/traverse": "^7.23.0",
+ "@babel/types": "^7.23.0",
+ "convert-source-map": "^2.0.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.3",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/babel"
+ }
+ },
+ "node_modules/@babel/generator": {
+ "version": "7.23.6",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz",
+ "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.23.6",
+ "@jridgewell/gen-mapping": "^0.3.2",
+ "@jridgewell/trace-mapping": "^0.3.17",
+ "jsesc": "^2.5.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz",
+ "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/compat-data": "^7.22.9",
+ "@babel/helper-validator-option": "^7.22.15",
+ "browserslist": "^4.21.9",
+ "lru-cache": "^5.1.1",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-environment-visitor": {
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
+ "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-function-name": {
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
+ "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/template": "^7.22.15",
+ "@babel/types": "^7.23.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-hoist-variables": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
+ "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-imports": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz",
+ "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.22.15"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms": {
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.0.tgz",
+ "integrity": "sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-environment-visitor": "^7.22.20",
+ "@babel/helper-module-imports": "^7.22.15",
+ "@babel/helper-simple-access": "^7.22.5",
+ "@babel/helper-split-export-declaration": "^7.22.6",
+ "@babel/helper-validator-identifier": "^7.22.20"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-plugin-utils": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+ "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-simple-access": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz",
+ "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-split-export-declaration": {
+ "version": "7.22.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
+ "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.23.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz",
+ "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
+ "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-option": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz",
+ "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers": {
+ "version": "7.23.1",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.1.tgz",
+ "integrity": "sha512-chNpneuK18yW5Oxsr+t553UZzzAs3aZnFm4bxhebsNTeshrC95yA7l5yl7GBAG+JG1rF0F7zzD2EixK9mWSDoA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/template": "^7.22.15",
+ "@babel/traverse": "^7.23.0",
+ "@babel/types": "^7.23.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/highlight": {
+ "version": "7.23.4",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz",
+ "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.22.20",
+ "chalk": "^2.4.2",
+ "js-tokens": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.24.0",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.0.tgz",
+ "integrity": "sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==",
+ "dev": true,
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-jsx-self": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.22.5.tgz",
+ "integrity": "sha512-nTh2ogNUtxbiSbxaT4Ds6aXnXEipHweN9YRgOX/oNXdf0cCrGn/+2LozFa3lnPV5D90MkjhgckCPBrsoSc1a7g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-jsx-source": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.22.5.tgz",
+ "integrity": "sha512-yIiRO6yobeEIaI0RTbIr8iAK9FcBHLtZq0S89ZPjDLQXBA4xvghaKqI0etp/tF3htTM0sazJKKLz9oEiGRtu7w==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/runtime": {
+ "version": "7.23.1",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.1.tgz",
+ "integrity": "sha512-hC2v6p8ZSI/W0HUzh3V8C5g+NwSKzKPtJwSpTjwl0o297GP9+ZLQSkdvHz46CM3LqyoXxq+5G9komY+eSqSO0g==",
+ "dependencies": {
+ "regenerator-runtime": "^0.14.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/template": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
+ "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.22.13",
+ "@babel/parser": "^7.22.15",
+ "@babel/types": "^7.22.15"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse": {
+ "version": "7.24.0",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.0.tgz",
+ "integrity": "sha512-HfuJlI8qq3dEDmNU5ChzzpZRWq+oxCZQyMzIMEqLho+AQnhMnKQUzH6ydo3RBl/YjPCuk68Y6s0Gx0AeyULiWw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.23.5",
+ "@babel/generator": "^7.23.6",
+ "@babel/helper-environment-visitor": "^7.22.20",
+ "@babel/helper-function-name": "^7.23.0",
+ "@babel/helper-hoist-variables": "^7.22.5",
+ "@babel/helper-split-export-declaration": "^7.22.6",
+ "@babel/parser": "^7.24.0",
+ "@babel/types": "^7.24.0",
+ "debug": "^4.3.1",
+ "globals": "^11.1.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.24.0",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz",
+ "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.23.4",
+ "@babel/helper-validator-identifier": "^7.22.20",
+ "to-fast-properties": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@emotion/hash": {
+ "version": "0.9.1",
+ "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz",
+ "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ=="
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
+ "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
+ "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
+ "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
+ "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
+ "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
+ "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
+ "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
+ "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
+ "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
+ "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
+ "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
+ "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
+ "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
+ "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
+ "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
+ "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
+ "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
+ "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
+ "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
+ "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
+ "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
+ "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
+ "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
+ "dev": true,
+ "dependencies": {
+ "eslint-visitor-keys": "^3.3.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+ }
+ },
+ "node_modules/@eslint-community/regexpp": {
+ "version": "4.9.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.9.1.tgz",
+ "integrity": "sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA==",
+ "dev": true,
+ "engines": {
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@eslint/eslintrc": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz",
+ "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==",
+ "dev": true,
+ "dependencies": {
+ "ajv": "^6.12.4",
+ "debug": "^4.3.2",
+ "espree": "^9.6.0",
+ "globals": "^13.19.0",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^4.1.0",
+ "minimatch": "^3.1.2",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/globals": {
+ "version": "13.23.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz",
+ "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==",
+ "dev": true,
+ "dependencies": {
+ "type-fest": "^0.20.2"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@eslint/js": {
+ "version": "8.51.0",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.51.0.tgz",
+ "integrity": "sha512-HxjQ8Qn+4SI3/AFv6sOrDB+g6PpUTDwSJiQqOrnneEk8L71161srI9gjzzZvYVbzHiVg/BvcH95+cK/zfIt4pg==",
+ "dev": true,
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@floating-ui/core": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.5.0.tgz",
+ "integrity": "sha512-kK1h4m36DQ0UHGj5Ah4db7R0rHemTqqO0QLvUqi1/mUUp3LuAWbWxdxSIf/XsnH9VS6rRVPLJCncjRzUvyCLXg==",
+ "dependencies": {
+ "@floating-ui/utils": "^0.1.3"
+ }
+ },
+ "node_modules/@floating-ui/dom": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.5.3.tgz",
+ "integrity": "sha512-ClAbQnEqJAKCJOEbbLo5IUlZHkNszqhuxS4fHAVxRPXPya6Ysf2G8KypnYcOTpx6I8xcgF9bbHb6g/2KpbV8qA==",
+ "dependencies": {
+ "@floating-ui/core": "^1.4.2",
+ "@floating-ui/utils": "^0.1.3"
+ }
+ },
+ "node_modules/@floating-ui/utils": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.6.tgz",
+ "integrity": "sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A=="
+ },
+ "node_modules/@fluentui/date-time-utilities": {
+ "version": "8.5.16",
+ "resolved": "https://registry.npmjs.org/@fluentui/date-time-utilities/-/date-time-utilities-8.5.16.tgz",
+ "integrity": "sha512-l+mLfJ2VhdHjBpELLLPDaWgT7GMLynm2aqR7SttbEb6Jh7hc/7ck1MWm93RTb3gYVHYai8SENqimNcvIxHt/zg==",
+ "dependencies": {
+ "@fluentui/set-version": "^8.2.14",
+ "tslib": "^2.1.0"
+ }
+ },
+ "node_modules/@fluentui/dom-utilities": {
+ "version": "2.2.14",
+ "resolved": "https://registry.npmjs.org/@fluentui/dom-utilities/-/dom-utilities-2.2.14.tgz",
+ "integrity": "sha512-+4DVm5sNfJh+l8fM+7ylpOkGNZkNr4X1z1uKQPzRJ1PRhlnvc6vLpWNNicGwpjTbgufSrVtGKXwP5sf++r81lg==",
+ "dependencies": {
+ "@fluentui/set-version": "^8.2.14",
+ "tslib": "^2.1.0"
+ }
+ },
+ "node_modules/@fluentui/font-icons-mdl2": {
+ "version": "8.5.32",
+ "resolved": "https://registry.npmjs.org/@fluentui/font-icons-mdl2/-/font-icons-mdl2-8.5.32.tgz",
+ "integrity": "sha512-PCZMijJlDQ5Zy8oNb80vUD6I4ORiR03qFgDT8o08mAGu+KzQO96q4jm0rzPRQuI9CO7pDD/6naOo8UVrmhZ2Aw==",
+ "dependencies": {
+ "@fluentui/set-version": "^8.2.14",
+ "@fluentui/style-utilities": "^8.10.3",
+ "@fluentui/utilities": "^8.13.24",
+ "tslib": "^2.1.0"
+ }
+ },
+ "node_modules/@fluentui/foundation-legacy": {
+ "version": "8.2.52",
+ "resolved": "https://registry.npmjs.org/@fluentui/foundation-legacy/-/foundation-legacy-8.2.52.tgz",
+ "integrity": "sha512-tHCD0m58Zja7wN1FTsvj4Gaj0B22xOhRTpyDzyvxRfjFGYPpR2Jgx/y/KRB3JTOX5EfJHAVzInyWZBeN5IfsVA==",
+ "dependencies": {
+ "@fluentui/merge-styles": "^8.5.15",
+ "@fluentui/set-version": "^8.2.14",
+ "@fluentui/style-utilities": "^8.10.3",
+ "@fluentui/utilities": "^8.13.24",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.8.0 <19.0.0",
+ "react": ">=16.8.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/keyboard-key": {
+ "version": "0.4.14",
+ "resolved": "https://registry.npmjs.org/@fluentui/keyboard-key/-/keyboard-key-0.4.14.tgz",
+ "integrity": "sha512-XzZHcyFEM20H23h3i15UpkHi2AhRBriXPGAHq0Jm98TKFppXehedjjEFuUsh+CyU5JKBhDalWp8TAQ1ArpNzow==",
+ "dependencies": {
+ "tslib": "^2.1.0"
+ }
+ },
+ "node_modules/@fluentui/keyboard-keys": {
+ "version": "9.0.7",
+ "resolved": "https://registry.npmjs.org/@fluentui/keyboard-keys/-/keyboard-keys-9.0.7.tgz",
+ "integrity": "sha512-vaQ+lOveQTdoXJYqDQXWb30udSfTVcIuKk1rV0X0eGAgcHeSDeP1HxMy+OgHOQZH3OiBH4ZYeWxb+tmfiDiygQ==",
+ "dependencies": {
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "node_modules/@fluentui/merge-styles": {
+ "version": "8.5.15",
+ "resolved": "https://registry.npmjs.org/@fluentui/merge-styles/-/merge-styles-8.5.15.tgz",
+ "integrity": "sha512-4CdKwo4k1Un2QLulpSVIz/KMgLNBMgin4NPyapmKDMVuO1OOxJUqfocubRGNO5x9mKgAMMYwBKGO9i0uxMMpJw==",
+ "dependencies": {
+ "@fluentui/set-version": "^8.2.14",
+ "tslib": "^2.1.0"
+ }
+ },
+ "node_modules/@fluentui/priority-overflow": {
+ "version": "9.1.9",
+ "resolved": "https://registry.npmjs.org/@fluentui/priority-overflow/-/priority-overflow-9.1.9.tgz",
+ "integrity": "sha512-+YlmuQ2E2le/FsJHKQPgs/vx2q4nDFXTN1yDLht2RUQl8/wsl7AHorHyMU/9ETPoxVWP+fFMnj3rTV+e5vWirg==",
+ "dependencies": {
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "node_modules/@fluentui/react": {
+ "version": "8.115.5",
+ "resolved": "https://registry.npmjs.org/@fluentui/react/-/react-8.115.5.tgz",
+ "integrity": "sha512-/Dmtf52r1pd2tbJ6NqbC65Zs+V/lOharui2uTtc0GxaMr3QREUWUkojtxKFwLVHqCrO1NzcIZm6siqR4z6ucRw==",
+ "dependencies": {
+ "@fluentui/date-time-utilities": "^8.5.16",
+ "@fluentui/font-icons-mdl2": "^8.5.32",
+ "@fluentui/foundation-legacy": "^8.2.52",
+ "@fluentui/merge-styles": "^8.5.15",
+ "@fluentui/react-focus": "^8.8.40",
+ "@fluentui/react-hooks": "^8.6.36",
+ "@fluentui/react-portal-compat-context": "^9.0.11",
+ "@fluentui/react-window-provider": "^2.2.18",
+ "@fluentui/set-version": "^8.2.14",
+ "@fluentui/style-utilities": "^8.10.3",
+ "@fluentui/theme": "^2.6.41",
+ "@fluentui/utilities": "^8.13.24",
+ "@microsoft/load-themed-styles": "^1.10.26",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.8.0 <19.0.0",
+ "@types/react-dom": ">=16.8.0 <19.0.0",
+ "react": ">=16.8.0 <19.0.0",
+ "react-dom": ">=16.8.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-accordion": {
+ "version": "9.3.27",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-accordion/-/react-accordion-9.3.27.tgz",
+ "integrity": "sha512-JBG5werMVMqpZJrQeGqrVyF7AOALkFrzQH4MZ0Pcf9zo3qnZ62QUz7YEj+Zl/In7jdfQhRTJ8grf47c4b6Nsiw==",
+ "dependencies": {
+ "@fluentui/react-aria": "^9.3.44",
+ "@fluentui/react-context-selector": "^9.1.42",
+ "@fluentui/react-icons": "^2.0.217",
+ "@fluentui/react-jsx-runtime": "^9.0.19",
+ "@fluentui/react-shared-contexts": "^9.12.0",
+ "@fluentui/react-tabster": "^9.14.4",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0",
+ "scheduler": "^0.19.0 || ^0.20.0"
+ }
+ },
+ "node_modules/@fluentui/react-alert": {
+ "version": "9.0.0-beta.91",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-alert/-/react-alert-9.0.0-beta.91.tgz",
+ "integrity": "sha512-cH7I64f2uq7x7Ly4oaapZZY9EU+xbqmvgJAgi7Px8LwvC3zohI1RZtlpaTKitjR3Aq51YYd9tP3VU8+1W58PwA==",
+ "dependencies": {
+ "@fluentui/react-avatar": "^9.5.45",
+ "@fluentui/react-button": "^9.3.54",
+ "@fluentui/react-icons": "^2.0.217",
+ "@fluentui/react-jsx-runtime": "^9.0.19",
+ "@fluentui/react-tabster": "^9.14.4",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-aria": {
+ "version": "9.3.44",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-aria/-/react-aria-9.3.44.tgz",
+ "integrity": "sha512-D3pvGgYObBzO00lhwhuuMWbPOZccy5EaYLXXI3OvzYdTs6ias6xXsOCgdnvrQ8BsIKixNUbtfjjxWCCIcLr4cg==",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-avatar": {
+ "version": "9.5.45",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-avatar/-/react-avatar-9.5.45.tgz",
+ "integrity": "sha512-JEpjDO9O06IERUJQa0i19QLvA36vK81a3xuMln6rjDEbk53Lw5IohhzIAr2ozBGk61x4woJPiyP9hX0uol0ACA==",
+ "dependencies": {
+ "@fluentui/react-badge": "^9.2.13",
+ "@fluentui/react-context-selector": "^9.1.42",
+ "@fluentui/react-icons": "^2.0.217",
+ "@fluentui/react-jsx-runtime": "^9.0.19",
+ "@fluentui/react-popover": "^9.8.20",
+ "@fluentui/react-shared-contexts": "^9.12.0",
+ "@fluentui/react-tabster": "^9.14.4",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-tooltip": "^9.3.21",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0",
+ "scheduler": "^0.19.0 || ^0.20.0"
+ }
+ },
+ "node_modules/@fluentui/react-badge": {
+ "version": "9.2.13",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-badge/-/react-badge-9.2.13.tgz",
+ "integrity": "sha512-oK8U+VnaFHL0EM9t3f/G+IoVqRNEFILvTibLPufH8voDJbSQDZarXjNEUonovAUqGp4Y3TsCL6y27rRMi9TK/Q==",
+ "dependencies": {
+ "@fluentui/react-icons": "^2.0.217",
+ "@fluentui/react-jsx-runtime": "^9.0.19",
+ "@fluentui/react-shared-contexts": "^9.12.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-button": {
+ "version": "9.3.54",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-button/-/react-button-9.3.54.tgz",
+ "integrity": "sha512-hjwpwdSJgYcBVZhonM/h+q++69hNa4OoCkL+SXWyHjKc6UZn9QyUVbdUvyHkhA/K5MhKfzrv5Hw2i4PLJb2S6w==",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-aria": "^9.3.44",
+ "@fluentui/react-icons": "^2.0.217",
+ "@fluentui/react-jsx-runtime": "^9.0.19",
+ "@fluentui/react-shared-contexts": "^9.12.0",
+ "@fluentui/react-tabster": "^9.14.4",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-card": {
+ "version": "9.0.53",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-card/-/react-card-9.0.53.tgz",
+ "integrity": "sha512-fNKBzLnuU6zVU/YFdsuR63Y0LjjzMg6ptRztGqY92bWilmv8xQVLHhJmUqtw9WTnGu0KM7FmdZZLrCm5gEJM1w==",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-jsx-runtime": "^9.0.19",
+ "@fluentui/react-tabster": "^9.14.4",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-checkbox": {
+ "version": "9.1.55",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-checkbox/-/react-checkbox-9.1.55.tgz",
+ "integrity": "sha512-1XcTP/6SnHJrk41Qr1A/ntpF9sIVPZkG9YLUxXo1Cz3QeO1yik22GkEugupBlmeyOx4zs+Cwiasw0vZKBRUqew==",
+ "dependencies": {
+ "@fluentui/react-field": "^9.1.41",
+ "@fluentui/react-icons": "^2.0.217",
+ "@fluentui/react-jsx-runtime": "^9.0.19",
+ "@fluentui/react-label": "^9.1.49",
+ "@fluentui/react-shared-contexts": "^9.12.0",
+ "@fluentui/react-tabster": "^9.14.4",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-combobox": {
+ "version": "9.5.29",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-combobox/-/react-combobox-9.5.29.tgz",
+ "integrity": "sha512-IrZGFNL3J+AnN92nN3bD27HPWx++6hcfH/jgpxZGUBdG8F6fhixlItCkx2k4DxONWNNMlZQ/SGB5TXNO5lCP4g==",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-context-selector": "^9.1.42",
+ "@fluentui/react-field": "^9.1.41",
+ "@fluentui/react-icons": "^2.0.217",
+ "@fluentui/react-jsx-runtime": "^9.0.19",
+ "@fluentui/react-portal": "^9.4.0",
+ "@fluentui/react-positioning": "^9.10.0",
+ "@fluentui/react-shared-contexts": "^9.12.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0",
+ "scheduler": "^0.19.0 || ^0.20.0"
+ }
+ },
+ "node_modules/@fluentui/react-components": {
+ "version": "9.38.0",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-components/-/react-components-9.38.0.tgz",
+ "integrity": "sha512-lDmoYefKSeXjORmO8cvKlDQOkWDfKEuOrMSDci6orxgWnGrIONh6mDmHg7C+2H8DeIWBiK7Bigd75BAWt6TNQA==",
+ "dependencies": {
+ "@fluentui/react-accordion": "^9.3.27",
+ "@fluentui/react-alert": "9.0.0-beta.91",
+ "@fluentui/react-avatar": "^9.5.45",
+ "@fluentui/react-badge": "^9.2.13",
+ "@fluentui/react-button": "^9.3.54",
+ "@fluentui/react-card": "^9.0.53",
+ "@fluentui/react-checkbox": "^9.1.55",
+ "@fluentui/react-combobox": "^9.5.29",
+ "@fluentui/react-dialog": "^9.8.4",
+ "@fluentui/react-divider": "^9.2.49",
+ "@fluentui/react-drawer": "9.0.0",
+ "@fluentui/react-field": "^9.1.41",
+ "@fluentui/react-image": "^9.1.46",
+ "@fluentui/react-infobutton": "9.0.0-beta.75",
+ "@fluentui/react-infolabel": "^9.0.3",
+ "@fluentui/react-input": "^9.4.51",
+ "@fluentui/react-label": "^9.1.49",
+ "@fluentui/react-link": "^9.1.33",
+ "@fluentui/react-menu": "^9.12.31",
+ "@fluentui/react-message-bar": "^9.0.5",
+ "@fluentui/react-overflow": "^9.0.43",
+ "@fluentui/react-persona": "^9.2.55",
+ "@fluentui/react-popover": "^9.8.20",
+ "@fluentui/react-portal": "^9.4.0",
+ "@fluentui/react-positioning": "^9.10.0",
+ "@fluentui/react-progress": "^9.1.51",
+ "@fluentui/react-provider": "^9.12.0",
+ "@fluentui/react-radio": "^9.1.55",
+ "@fluentui/react-select": "^9.1.51",
+ "@fluentui/react-shared-contexts": "^9.12.0",
+ "@fluentui/react-skeleton": "^9.0.39",
+ "@fluentui/react-slider": "^9.1.55",
+ "@fluentui/react-spinbutton": "^9.2.51",
+ "@fluentui/react-spinner": "^9.3.29",
+ "@fluentui/react-switch": "^9.1.55",
+ "@fluentui/react-table": "^9.10.10",
+ "@fluentui/react-tabs": "^9.3.56",
+ "@fluentui/react-tabster": "^9.14.4",
+ "@fluentui/react-tags": "^9.0.9",
+ "@fluentui/react-text": "^9.3.46",
+ "@fluentui/react-textarea": "^9.3.51",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-toast": "^9.3.16",
+ "@fluentui/react-toolbar": "^9.1.55",
+ "@fluentui/react-tooltip": "^9.3.21",
+ "@fluentui/react-tree": "^9.4.12",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@fluentui/react-virtualizer": "9.0.0-alpha.56",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0",
+ "scheduler": "^0.19.0 || ^0.20.0"
+ }
+ },
+ "node_modules/@fluentui/react-context-selector": {
+ "version": "9.1.42",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-context-selector/-/react-context-selector-9.1.42.tgz",
+ "integrity": "sha512-Xq9JcPBCRLkCnrUd83qSFgEYZc1BYyxFXLamtev5Ok1SSF53XI4yqN7Y34A13fSu/Q2wGeZibHcCTHJIXad2sQ==",
+ "dependencies": {
+ "@fluentui/react-utilities": "^9.15.2",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0",
+ "scheduler": "^0.19.0 || ^0.20.0"
+ }
+ },
+ "node_modules/@fluentui/react-dialog": {
+ "version": "9.8.4",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-dialog/-/react-dialog-9.8.4.tgz",
+ "integrity": "sha512-H8PNiYnsycpK5+I7rO/IhRn5hZImeAmdc7A9t9lNMGTIDELSTRS/aOOV7D8dENY0fegD6oNi4gLBM+k6WOAc6g==",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-aria": "^9.3.44",
+ "@fluentui/react-context-selector": "^9.1.42",
+ "@fluentui/react-icons": "^2.0.217",
+ "@fluentui/react-jsx-runtime": "^9.0.19",
+ "@fluentui/react-portal": "^9.4.0",
+ "@fluentui/react-shared-contexts": "^9.12.0",
+ "@fluentui/react-tabster": "^9.14.4",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1",
+ "react-transition-group": "^4.4.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-divider": {
+ "version": "9.2.49",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-divider/-/react-divider-9.2.49.tgz",
+ "integrity": "sha512-XS0QWsbU0YHhZCtssYT3hT6825im8COcnSJ96KAj7rpffhlkOmpCdewNIQr/TyFrcLgfYg8jdKWO9QSmZpl1qg==",
+ "dependencies": {
+ "@fluentui/react-jsx-runtime": "^9.0.19",
+ "@fluentui/react-shared-contexts": "^9.12.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-drawer": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-drawer/-/react-drawer-9.0.0.tgz",
+ "integrity": "sha512-HWXtBwFQsDklhDiS3O5h2OokJ3B/kKMOXPHE8/vjELK4TsUDaV9gkr2IEHIlhx1OR7oo+N5wKmsbp+B7FNFspA==",
+ "dependencies": {
+ "@fluentui/react-dialog": "^9.8.4",
+ "@fluentui/react-jsx-runtime": "^9.0.19",
+ "@fluentui/react-motion-preview": "^0.5.1",
+ "@fluentui/react-shared-contexts": "^9.12.0",
+ "@fluentui/react-tabster": "^9.14.4",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-field": {
+ "version": "9.1.41",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-field/-/react-field-9.1.41.tgz",
+ "integrity": "sha512-0HmXM7HMAkabLuPDhlXKJjVg9hY5fGtgtrT1sVW3GgqiqYU+P5RYD67X4R28MSzrPvUVAc1tv9a3+UIQFF59QQ==",
+ "dependencies": {
+ "@fluentui/react-context-selector": "^9.1.42",
+ "@fluentui/react-icons": "^2.0.217",
+ "@fluentui/react-jsx-runtime": "^9.0.19",
+ "@fluentui/react-label": "^9.1.49",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-focus": {
+ "version": "8.8.40",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-focus/-/react-focus-8.8.40.tgz",
+ "integrity": "sha512-ha0CbLv5EIbjYCtQky6LVZObxOeMfhixrgrzfXm3Ta2eGs1NyZRDm1VeM6acOolWB/8QiN/CbdGckjALli8L2g==",
+ "dependencies": {
+ "@fluentui/keyboard-key": "^0.4.14",
+ "@fluentui/merge-styles": "^8.5.15",
+ "@fluentui/set-version": "^8.2.14",
+ "@fluentui/style-utilities": "^8.10.3",
+ "@fluentui/utilities": "^8.13.24",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.8.0 <19.0.0",
+ "react": ">=16.8.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-hooks": {
+ "version": "8.6.36",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-hooks/-/react-hooks-8.6.36.tgz",
+ "integrity": "sha512-kI0Z4Q4xHUs4SOmmI5n5OH5fPckqMSCovTRpiuxzCO2TNzLmfC861+nqf4Ygw/ChqNm2gWNZZfUADfnNAEsq+Q==",
+ "dependencies": {
+ "@fluentui/react-window-provider": "^2.2.18",
+ "@fluentui/set-version": "^8.2.14",
+ "@fluentui/utilities": "^8.13.24",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.8.0 <19.0.0",
+ "react": ">=16.8.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-icons": {
+ "version": "2.0.222",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-icons/-/react-icons-2.0.222.tgz",
+ "integrity": "sha512-3Qy9GPww9rj51mJ6iEGCqSBEDZ8qBK+FK0BdtcVF4LFxpnPbB45hEf2dZ6LBQbfuKgH8NB3QHRSky75DjrjfdA==",
+ "dependencies": {
+ "@griffel/react": "^1.0.0",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-image": {
+ "version": "9.1.46",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-image/-/react-image-9.1.46.tgz",
+ "integrity": "sha512-J7fOUyF+xNvdfBBCthmW2VV3LMCdD4kDa4TzjAbMT9a/gafeXWaY2+gcEPtuBQ5gLAKv5HDVlEtxTmK3Bj+OAA==",
+ "dependencies": {
+ "@fluentui/react-jsx-runtime": "^9.0.19",
+ "@fluentui/react-shared-contexts": "^9.12.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-infobutton": {
+ "version": "9.0.0-beta.75",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-infobutton/-/react-infobutton-9.0.0-beta.75.tgz",
+ "integrity": "sha512-axkJNnQGHpiOrrXOdJ9qrR9RNM626fYc4G/uUv9lgBp9NSD0ov15lFnzzjFWx34zTTfbmXZUVDzUEyzXd9g0xA==",
+ "dependencies": {
+ "@fluentui/react-icons": "^2.0.217",
+ "@fluentui/react-jsx-runtime": "^9.0.19",
+ "@fluentui/react-label": "^9.1.49",
+ "@fluentui/react-popover": "^9.8.20",
+ "@fluentui/react-tabster": "^9.14.4",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-infolabel": {
+ "version": "9.0.3",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-infolabel/-/react-infolabel-9.0.3.tgz",
+ "integrity": "sha512-lK0rV2tB4RAsqeHc0UuFnsPFfr/gcA0TfbcdWyBCtGsRIB5RLsIGM1o3t/p0SfT1s1N0AmYi9abh5Yfhgfs7sw==",
+ "dependencies": {
+ "@fluentui/react-icons": "^2.0.217",
+ "@fluentui/react-jsx-runtime": "^9.0.19",
+ "@fluentui/react-label": "^9.1.49",
+ "@fluentui/react-popover": "^9.8.20",
+ "@fluentui/react-tabster": "^9.14.4",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.8.0 <19.0.0",
+ "@types/react-dom": ">=16.8.0 <19.0.0",
+ "react": ">=16.8.0 <19.0.0",
+ "react-dom": ">=16.8.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-input": {
+ "version": "9.4.51",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-input/-/react-input-9.4.51.tgz",
+ "integrity": "sha512-fdjU49z+qUNiOOpCMbV/sGyFJK2A5v53iIX26Ukxw/JLxXAaGnhCsKxkZgvx4PNyYRxWuYVwfkV0kUR2jjiN9Q==",
+ "dependencies": {
+ "@fluentui/react-field": "^9.1.41",
+ "@fluentui/react-jsx-runtime": "^9.0.19",
+ "@fluentui/react-shared-contexts": "^9.12.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-jsx-runtime": {
+ "version": "9.0.19",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-jsx-runtime/-/react-jsx-runtime-9.0.19.tgz",
+ "integrity": "sha512-aSz/H86hsJQTQ7CkxfH4BIiwDRzIuQs9XKNCiVHNzk6AX2cEeA12SM4NSeT5VmksM+D7vL6J0EBmUGDyX6bY5A==",
+ "dependencies": {
+ "@fluentui/react-utilities": "^9.15.2",
+ "@swc/helpers": "^0.5.1",
+ "react-is": "^17.0.2"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-jsx-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=="
+ },
+ "node_modules/@fluentui/react-label": {
+ "version": "9.1.49",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-label/-/react-label-9.1.49.tgz",
+ "integrity": "sha512-N8Wlork7ZfJIqiKxginAPy9TrX/ZbVU3DljWyw3cD9Y9u6HAaFeYBM7heRhLgJNByN/NxcArw54/l99hBka2bg==",
+ "dependencies": {
+ "@fluentui/react-jsx-runtime": "^9.0.19",
+ "@fluentui/react-shared-contexts": "^9.12.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-link": {
+ "version": "9.1.33",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-link/-/react-link-9.1.33.tgz",
+ "integrity": "sha512-MXXeyIrrawilx1+R25BzQV4zrWJ5PVIXrpPsFrmj9drkBvYBFceFhwjrzUxV1O51Q59Rpsh0I2Jz7rUwoGg8Qg==",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-jsx-runtime": "^9.0.19",
+ "@fluentui/react-shared-contexts": "^9.12.0",
+ "@fluentui/react-tabster": "^9.14.4",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-menu": {
+ "version": "9.12.31",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-menu/-/react-menu-9.12.31.tgz",
+ "integrity": "sha512-PiWj4w9KnUU6nD+XAqDZR5a+6VquxbyL/Z6vEH+3MfU1769dR2mj68dKfLBZWmQKteSWJvqx4ZBR1KZwsYcccA==",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-aria": "^9.3.44",
+ "@fluentui/react-context-selector": "^9.1.42",
+ "@fluentui/react-icons": "^2.0.217",
+ "@fluentui/react-jsx-runtime": "^9.0.19",
+ "@fluentui/react-portal": "^9.4.0",
+ "@fluentui/react-positioning": "^9.10.0",
+ "@fluentui/react-shared-contexts": "^9.12.0",
+ "@fluentui/react-tabster": "^9.14.4",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0",
+ "scheduler": "^0.19.0 || ^0.20.0"
+ }
+ },
+ "node_modules/@fluentui/react-message-bar": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-message-bar/-/react-message-bar-9.0.5.tgz",
+ "integrity": "sha512-0q+ROGpIhguGKC4hbopSB0QSA8oEZKgYom/GsqX57J+OZi3sbpp7zdihS+j9pvvuHT22kKh6ASZG24rNTFtrVg==",
+ "dependencies": {
+ "@fluentui/react-button": "^9.3.54",
+ "@fluentui/react-icons": "^2.0.217",
+ "@fluentui/react-jsx-runtime": "^9.0.19",
+ "@fluentui/react-shared-contexts": "^9.12.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1",
+ "react-transition-group": "^4.4.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.8.0 <19.0.0",
+ "@types/react-dom": ">=16.8.0 <19.0.0",
+ "react": ">=16.8.0 <19.0.0",
+ "react-dom": ">=16.8.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-motion-preview": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-motion-preview/-/react-motion-preview-0.5.1.tgz",
+ "integrity": "sha512-tg7q73/mXR0ZhlZPn5nATIDmefDMN02DEnfhAjcio2by0tma15OV/RNlbEsoqUR2xDu9BSjieSS8TIZTgjq3SQ==",
+ "dependencies": {
+ "@fluentui/react-jsx-runtime": "^9.0.19",
+ "@fluentui/react-shared-contexts": "^9.12.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-overflow": {
+ "version": "9.0.43",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-overflow/-/react-overflow-9.0.43.tgz",
+ "integrity": "sha512-YQDar2pw3WKpgK+gYg16l6Lsfz7HF4YLckOFlT4AujhrpdN6vEwDfw9Afj8/kSvJy5iGs0rqw8s4KokRWZArxA==",
+ "dependencies": {
+ "@fluentui/priority-overflow": "^9.1.9",
+ "@fluentui/react-context-selector": "^9.1.42",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0",
+ "scheduler": "^0.19.0 || ^0.20.0"
+ }
+ },
+ "node_modules/@fluentui/react-persona": {
+ "version": "9.2.55",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-persona/-/react-persona-9.2.55.tgz",
+ "integrity": "sha512-/CeY60wMXyZY67OPFuhHtli+ToDq2dWHPYGUIVqCWfAuLwvvWqbi8jPTlVOflGOWJJuomVeK/7iRb0gUJPobHg==",
+ "dependencies": {
+ "@fluentui/react-avatar": "^9.5.45",
+ "@fluentui/react-badge": "^9.2.13",
+ "@fluentui/react-jsx-runtime": "^9.0.19",
+ "@fluentui/react-shared-contexts": "^9.12.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-popover": {
+ "version": "9.8.20",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-popover/-/react-popover-9.8.20.tgz",
+ "integrity": "sha512-Pi69IIFSTIsEre//bQaHrPKGpN64E326MpCJ7b3QS4oyS0w/z3mv0ym893bLY4ktHbw6EZSWf+WchVJpfGYybA==",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-aria": "^9.3.44",
+ "@fluentui/react-context-selector": "^9.1.42",
+ "@fluentui/react-jsx-runtime": "^9.0.19",
+ "@fluentui/react-portal": "^9.4.0",
+ "@fluentui/react-positioning": "^9.10.0",
+ "@fluentui/react-shared-contexts": "^9.12.0",
+ "@fluentui/react-tabster": "^9.14.4",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0",
+ "scheduler": "^0.19.0 || ^0.20.0"
+ }
+ },
+ "node_modules/@fluentui/react-portal": {
+ "version": "9.4.0",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-portal/-/react-portal-9.4.0.tgz",
+ "integrity": "sha512-fiL8eFC7g9yurWEbfrpoFej9dv/cmIYWZcmNmvZL9jy6HsTnFS92mE31cKmFJErpqbsIxNFWK9TMs6zT8a4fTQ==",
+ "dependencies": {
+ "@fluentui/react-shared-contexts": "^9.12.0",
+ "@fluentui/react-tabster": "^9.14.4",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1",
+ "use-disposable": "^1.0.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-portal-compat-context": {
+ "version": "9.0.11",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-portal-compat-context/-/react-portal-compat-context-9.0.11.tgz",
+ "integrity": "sha512-ubvW/ej0O+Pago9GH3mPaxzUgsNnBoqvghNamWjyKvZIViyaXUG6+sgcAl721R+qGAFac+A20akI5qDJz/xtdg==",
+ "dependencies": {
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-positioning": {
+ "version": "9.10.0",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-positioning/-/react-positioning-9.10.0.tgz",
+ "integrity": "sha512-2k6e9AUi2yB2GPvgPSCQ42rG+yDkpAs2IfQpaO5ht4L/UxXyxEQUltcPJOQDiPE271WOfPI4rX201CLluHuNSQ==",
+ "dependencies": {
+ "@floating-ui/dom": "^1.2.0",
+ "@fluentui/react-shared-contexts": "^9.12.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-progress": {
+ "version": "9.1.51",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-progress/-/react-progress-9.1.51.tgz",
+ "integrity": "sha512-z2evxOKqgppbwrUajG4h0LbXax0sJ15t30gKtCzfY7TuvWqtmpImod6jOFyidWh9PLnNlNZeyJj2zQZ3VNPC6g==",
+ "dependencies": {
+ "@fluentui/react-field": "^9.1.41",
+ "@fluentui/react-jsx-runtime": "^9.0.19",
+ "@fluentui/react-shared-contexts": "^9.12.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-provider": {
+ "version": "9.12.0",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-provider/-/react-provider-9.12.0.tgz",
+ "integrity": "sha512-ocS0247BX7x9rUIozs0mMNGfDkjNIcFRq20cwPzpEUUHgKj/Dw0Ae1sXUORRUWG/z+/nalQx49ccqf6FcqmoYw==",
+ "dependencies": {
+ "@fluentui/react-icons": "^2.0.217",
+ "@fluentui/react-jsx-runtime": "^9.0.19",
+ "@fluentui/react-shared-contexts": "^9.12.0",
+ "@fluentui/react-tabster": "^9.14.4",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/core": "^1.14.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-radio": {
+ "version": "9.1.55",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-radio/-/react-radio-9.1.55.tgz",
+ "integrity": "sha512-WxAtrpKwLjhSVQ796DeayJ3aAe4zVYXlGgWMyN9/zjNruve7jNrybMMUw6XPBwjw+Ycfk6P3r/rCasG2SphzOg==",
+ "dependencies": {
+ "@fluentui/react-field": "^9.1.41",
+ "@fluentui/react-icons": "^2.0.217",
+ "@fluentui/react-jsx-runtime": "^9.0.19",
+ "@fluentui/react-label": "^9.1.49",
+ "@fluentui/react-shared-contexts": "^9.12.0",
+ "@fluentui/react-tabster": "^9.14.4",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0",
+ "scheduler": "^0.19.0 || ^0.20.0"
+ }
+ },
+ "node_modules/@fluentui/react-select": {
+ "version": "9.1.51",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-select/-/react-select-9.1.51.tgz",
+ "integrity": "sha512-sUpfOM9Aj+N9cjPkW+LcmZW+FFk1asPMt8GiMP68szFwxcLwXkOb3rvG26v6C9fexGKpk4SA9giZ0iuaTnlsJA==",
+ "dependencies": {
+ "@fluentui/react-field": "^9.1.41",
+ "@fluentui/react-icons": "^2.0.217",
+ "@fluentui/react-jsx-runtime": "^9.0.19",
+ "@fluentui/react-shared-contexts": "^9.12.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-shared-contexts": {
+ "version": "9.12.0",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-shared-contexts/-/react-shared-contexts-9.12.0.tgz",
+ "integrity": "sha512-1HSFgrLB9631E4XXLemotfqTSxnKEZlcx+h7kDn2Q+GtK6dvpjaDtsnEPvC0aoCbXz7UTyCsl6OIPU+yjcfhyw==",
+ "dependencies": {
+ "@fluentui/react-theme": "^9.1.16",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-skeleton": {
+ "version": "9.0.39",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-skeleton/-/react-skeleton-9.0.39.tgz",
+ "integrity": "sha512-O5oRgbEsR8mBck39rJJKPHDCUqYsko6mOpqMrcB196BBp2vcI6usrU1i5lJ3rN48KmiT7OMaeRotwwW32ep4/A==",
+ "dependencies": {
+ "@fluentui/react-field": "^9.1.41",
+ "@fluentui/react-jsx-runtime": "^9.0.19",
+ "@fluentui/react-shared-contexts": "^9.12.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-slider": {
+ "version": "9.1.55",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-slider/-/react-slider-9.1.55.tgz",
+ "integrity": "sha512-wgaOkVGlvEd/d5j9mDSI93zhmoYdnkgQy7S96CKPoPbA0N0MbOIApWz5uzQBu6X0mUfmI66jaafYrQ+u1vWwgA==",
+ "dependencies": {
+ "@fluentui/react-field": "^9.1.41",
+ "@fluentui/react-jsx-runtime": "^9.0.19",
+ "@fluentui/react-shared-contexts": "^9.12.0",
+ "@fluentui/react-tabster": "^9.14.4",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-spinbutton": {
+ "version": "9.2.51",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-spinbutton/-/react-spinbutton-9.2.51.tgz",
+ "integrity": "sha512-adlILeKAobCtLVaQpJY+PvJPsMaZVM9EIIMyi2s083XzgXUij6Xwa9c/89vyUO5f5P5HkYm+V12KqnOOoXzhBQ==",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-field": "^9.1.41",
+ "@fluentui/react-icons": "^2.0.217",
+ "@fluentui/react-jsx-runtime": "^9.0.19",
+ "@fluentui/react-shared-contexts": "^9.12.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-spinner": {
+ "version": "9.3.29",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-spinner/-/react-spinner-9.3.29.tgz",
+ "integrity": "sha512-oF4HsUrtyZxMXManIH0Q0+QtRf39aPq8bFc5umItsqi2uT+hom8fSc5yPPOgFAma3E+ioUxfFbM+dC3Zapzy2Q==",
+ "dependencies": {
+ "@fluentui/react-jsx-runtime": "^9.0.19",
+ "@fluentui/react-label": "^9.1.49",
+ "@fluentui/react-shared-contexts": "^9.12.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-switch": {
+ "version": "9.1.55",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-switch/-/react-switch-9.1.55.tgz",
+ "integrity": "sha512-gMi9Yv4DmVYsF+DJEjdoI5hEHH8nPpdUV8l2m0hjbV3IuBpMXD2RVAGeo/T6GMHtafk9v2PFsFEy2xBjcBOiDA==",
+ "dependencies": {
+ "@fluentui/react-field": "^9.1.41",
+ "@fluentui/react-icons": "^2.0.217",
+ "@fluentui/react-jsx-runtime": "^9.0.19",
+ "@fluentui/react-label": "^9.1.49",
+ "@fluentui/react-shared-contexts": "^9.12.0",
+ "@fluentui/react-tabster": "^9.14.4",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-table": {
+ "version": "9.10.10",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-table/-/react-table-9.10.10.tgz",
+ "integrity": "sha512-spnXKUJyPx8AC+IBSIVY+4T18Cbrk0nnRu38HcBaTnnaFv2z6lr1AiYbQ0Tyul42YiQBipSpl0mUML/kk0B0+A==",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-aria": "^9.3.44",
+ "@fluentui/react-avatar": "^9.5.45",
+ "@fluentui/react-checkbox": "^9.1.55",
+ "@fluentui/react-context-selector": "^9.1.42",
+ "@fluentui/react-icons": "^2.0.217",
+ "@fluentui/react-jsx-runtime": "^9.0.19",
+ "@fluentui/react-radio": "^9.1.55",
+ "@fluentui/react-shared-contexts": "^9.12.0",
+ "@fluentui/react-tabster": "^9.14.4",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-tabs": {
+ "version": "9.3.56",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-tabs/-/react-tabs-9.3.56.tgz",
+ "integrity": "sha512-5uaHdXV6pNSPnfpEhar6UjkoSaUNNJZEDxe5cBECC8IkvbC9lBkq6LdO5EB+Bdnul002dy4D0Aj0SGNI7DuqvQ==",
+ "dependencies": {
+ "@fluentui/react-context-selector": "^9.1.42",
+ "@fluentui/react-jsx-runtime": "^9.0.19",
+ "@fluentui/react-shared-contexts": "^9.12.0",
+ "@fluentui/react-tabster": "^9.14.4",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0",
+ "scheduler": "^0.19.0 || ^0.20.0"
+ }
+ },
+ "node_modules/@fluentui/react-tabster": {
+ "version": "9.14.4",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-tabster/-/react-tabster-9.14.4.tgz",
+ "integrity": "sha512-TVsYcVoonGuoO3naHwurrWx4WcQIAefGljb8VxzRnZb5MuGY6vLk3jlsuQWYWyO24o4YH2fk7n5oSW6ugA1MAA==",
+ "dependencies": {
+ "@fluentui/react-shared-contexts": "^9.12.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1",
+ "keyborg": "^2.1.0",
+ "tabster": "^4.8.0"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-tags": {
+ "version": "9.0.9",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-tags/-/react-tags-9.0.9.tgz",
+ "integrity": "sha512-zKO8+q3hjMr7b+c934tYy5sKebiSviMwPjKcRZc9cb9XuuyQwgDzul7WvuSBfZnuR9u/gk+6o7TRkQxjcQcAew==",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-aria": "^9.3.44",
+ "@fluentui/react-avatar": "^9.5.45",
+ "@fluentui/react-icons": "^2.0.217",
+ "@fluentui/react-jsx-runtime": "^9.0.19",
+ "@fluentui/react-shared-contexts": "^9.12.0",
+ "@fluentui/react-tabster": "^9.14.4",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-text": {
+ "version": "9.3.46",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-text/-/react-text-9.3.46.tgz",
+ "integrity": "sha512-YrRxA3SCYn/NQj2BIesilXhjD8tFedYvJUjZUQMZD1Lm9ccFYnF/sI2WNz71Ta563rl0L9Ia2KMmNwD/XMZJoA==",
+ "dependencies": {
+ "@fluentui/react-jsx-runtime": "^9.0.19",
+ "@fluentui/react-shared-contexts": "^9.12.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-textarea": {
+ "version": "9.3.51",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-textarea/-/react-textarea-9.3.51.tgz",
+ "integrity": "sha512-FmPzQxwC4GLpke3uRdgNVnKHJRcrKpHLrmV2yyvcVwMEHn3OnH0QxMCMZhaDdedbAGAWO6Z2+kWfsdfTnrG99A==",
+ "dependencies": {
+ "@fluentui/react-field": "^9.1.41",
+ "@fluentui/react-jsx-runtime": "^9.0.19",
+ "@fluentui/react-shared-contexts": "^9.12.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-theme": {
+ "version": "9.1.16",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-theme/-/react-theme-9.1.16.tgz",
+ "integrity": "sha512-QK2dGE5aQXN1UGdiEmGKpYGP3tHXIchLvFf8DEEOWnF4XBc9SiEPNFYkvLMJjHxZmDz4D670rsOPe0r5jFDEKQ==",
+ "dependencies": {
+ "@fluentui/tokens": "1.0.0-alpha.13",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "node_modules/@fluentui/react-toast": {
+ "version": "9.3.16",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-toast/-/react-toast-9.3.16.tgz",
+ "integrity": "sha512-NGU2oz4JgmX7MaglyKnYRY2pw7uKjQbPzQj0pxPFk1hMi7l30w46xJ24m74z01kqQYCCxl5hAjfICVIGIX07MQ==",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-aria": "^9.3.44",
+ "@fluentui/react-icons": "^2.0.217",
+ "@fluentui/react-jsx-runtime": "^9.0.19",
+ "@fluentui/react-portal": "^9.4.0",
+ "@fluentui/react-shared-contexts": "^9.12.0",
+ "@fluentui/react-tabster": "^9.14.4",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1",
+ "react-transition-group": "^4.4.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-toolbar": {
+ "version": "9.1.55",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-toolbar/-/react-toolbar-9.1.55.tgz",
+ "integrity": "sha512-Z4MDjZ4pH8P/5ttR5UlZ++aC1MzGcIHNWVqdO4DUpPHEaneBxuRzAYlMQlZW/IZLDw7JEfFwQLIP0GscfTtWUw==",
+ "dependencies": {
+ "@fluentui/react-button": "^9.3.54",
+ "@fluentui/react-context-selector": "^9.1.42",
+ "@fluentui/react-divider": "^9.2.49",
+ "@fluentui/react-jsx-runtime": "^9.0.19",
+ "@fluentui/react-radio": "^9.1.55",
+ "@fluentui/react-shared-contexts": "^9.12.0",
+ "@fluentui/react-tabster": "^9.14.4",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-tooltip": {
+ "version": "9.3.21",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-tooltip/-/react-tooltip-9.3.21.tgz",
+ "integrity": "sha512-9y77imd0lBSO/xA2fzbBHA0FRf5MMda+p1B1xQKk7cRhhz6TzVX83y7bdf6ewcWBVuZxqDCFc3SELI1gOZxEKQ==",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-jsx-runtime": "^9.0.19",
+ "@fluentui/react-portal": "^9.4.0",
+ "@fluentui/react-positioning": "^9.10.0",
+ "@fluentui/react-shared-contexts": "^9.12.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-tree": {
+ "version": "9.4.12",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-tree/-/react-tree-9.4.12.tgz",
+ "integrity": "sha512-01hBhQIVOpUHudAU/RvMk0i0yWYLnnF5rFPy6KWUgIs068gU+MEMuUn9+nCM9au5UGpGcgqr2840dmibSCGi1Q==",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-aria": "^9.3.44",
+ "@fluentui/react-avatar": "^9.5.45",
+ "@fluentui/react-button": "^9.3.54",
+ "@fluentui/react-checkbox": "^9.1.55",
+ "@fluentui/react-context-selector": "^9.1.42",
+ "@fluentui/react-icons": "^2.0.217",
+ "@fluentui/react-jsx-runtime": "^9.0.19",
+ "@fluentui/react-radio": "^9.1.55",
+ "@fluentui/react-shared-contexts": "^9.12.0",
+ "@fluentui/react-tabster": "^9.14.4",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-utilities": {
+ "version": "9.15.2",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-utilities/-/react-utilities-9.15.2.tgz",
+ "integrity": "sha512-Oq016/dHu7PXW5x/2RtLts1ULiyd7JctXFdvi9IacLs/J1nLfg2KSBzzLqKxtdyVvgbZ9Mlu6kPITbFtF9dsIA==",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-virtualizer": {
+ "version": "9.0.0-alpha.56",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-virtualizer/-/react-virtualizer-9.0.0-alpha.56.tgz",
+ "integrity": "sha512-IrJKFrpPO/uLA9dVUuzUEQ5LPHtlOHhykOKiGWWWUXsjJUSekTU17PL45fylaJmwsn4bDtWIFSNBW0FSQQrkLg==",
+ "dependencies": {
+ "@fluentui/react-jsx-runtime": "^9.0.19",
+ "@fluentui/react-shared-contexts": "^9.12.0",
+ "@fluentui/react-utilities": "^9.15.2",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-window-provider": {
+ "version": "2.2.18",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-window-provider/-/react-window-provider-2.2.18.tgz",
+ "integrity": "sha512-nBKqxd0P8NmIR0qzFvka1urE2LVbUm6cse1I1T7TcOVNYa5jDf5BrO06+JRZfwbn00IJqOnIVoP0qONqceypWQ==",
+ "dependencies": {
+ "@fluentui/set-version": "^8.2.14",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.8.0 <19.0.0",
+ "react": ">=16.8.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/set-version": {
+ "version": "8.2.14",
+ "resolved": "https://registry.npmjs.org/@fluentui/set-version/-/set-version-8.2.14.tgz",
+ "integrity": "sha512-f/QWJnSeyfAjGAqq57yjMb6a5ejPlwfzdExPmzFBuEOuupi8hHbV8Yno12XJcTW4I0KXEQGw+PUaM1aOf/j7jw==",
+ "dependencies": {
+ "tslib": "^2.1.0"
+ }
+ },
+ "node_modules/@fluentui/style-utilities": {
+ "version": "8.10.3",
+ "resolved": "https://registry.npmjs.org/@fluentui/style-utilities/-/style-utilities-8.10.3.tgz",
+ "integrity": "sha512-pyO9BGkwIxXaIMVT6ma98GIZAgTjGc0LZ5iUai9GLIrFLQWnIKnS//hgUx8qG4AecUeqZ26Wb0e+Ale9NyPQCQ==",
+ "dependencies": {
+ "@fluentui/merge-styles": "^8.5.15",
+ "@fluentui/set-version": "^8.2.14",
+ "@fluentui/theme": "^2.6.41",
+ "@fluentui/utilities": "^8.13.24",
+ "@microsoft/load-themed-styles": "^1.10.26",
+ "tslib": "^2.1.0"
+ }
+ },
+ "node_modules/@fluentui/theme": {
+ "version": "2.6.41",
+ "resolved": "https://registry.npmjs.org/@fluentui/theme/-/theme-2.6.41.tgz",
+ "integrity": "sha512-h9RguEzqzJ0+59ys5Kkp7JtsjhDUxBLmQunu5rpHp5Mp788OtEjI/n1a9FIcOAL/priPSQwXN7RbuDpeP7+aSw==",
+ "dependencies": {
+ "@fluentui/merge-styles": "^8.5.15",
+ "@fluentui/set-version": "^8.2.14",
+ "@fluentui/utilities": "^8.13.24",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.8.0 <19.0.0",
+ "react": ">=16.8.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/tokens": {
+ "version": "1.0.0-alpha.13",
+ "resolved": "https://registry.npmjs.org/@fluentui/tokens/-/tokens-1.0.0-alpha.13.tgz",
+ "integrity": "sha512-IzYysTTBkAH7tQZxYKpzhxYnTJkvwXhjhTOpmERgnqTFifHTP8/vaQjJAAm7dI/9zlDx1oN+y/I+KzL9bDLHZQ==",
+ "dependencies": {
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "node_modules/@fluentui/utilities": {
+ "version": "8.13.24",
+ "resolved": "https://registry.npmjs.org/@fluentui/utilities/-/utilities-8.13.24.tgz",
+ "integrity": "sha512-/jo6hWCzTGCx06l2baAMwsjjBZ/dyMouls53uNaQLUGUUhUwXh/DcDDXMqLRJB3MaH9zvgfvRw61iKmm2s9fIA==",
+ "dependencies": {
+ "@fluentui/dom-utilities": "^2.2.14",
+ "@fluentui/merge-styles": "^8.5.15",
+ "@fluentui/set-version": "^8.2.14",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.8.0 <19.0.0",
+ "react": ">=16.8.0 <19.0.0"
+ }
+ },
+ "node_modules/@griffel/core": {
+ "version": "1.15.0",
+ "resolved": "https://registry.npmjs.org/@griffel/core/-/core-1.15.0.tgz",
+ "integrity": "sha512-+2Li2x6zqQdVBSMbvGSJRxbMbOrXhCEEzX0BK6OMfjdMPJLoR2aaHuAwHL3J9dOpHzFrjp9MMEo4Jzwfo4l6Xw==",
+ "dependencies": {
+ "@emotion/hash": "^0.9.0",
+ "@griffel/style-types": "^1.0.2",
+ "csstype": "^3.1.2",
+ "rtl-css-js": "^1.16.1",
+ "stylis": "^4.2.0",
+ "tslib": "^2.1.0"
+ }
+ },
+ "node_modules/@griffel/react": {
+ "version": "1.5.18",
+ "resolved": "https://registry.npmjs.org/@griffel/react/-/react-1.5.18.tgz",
+ "integrity": "sha512-Y5L2zvfE+quMPSQPtViMmuDXNCIyJaeeQc5m30VMELgXYN0uk4nbFqwKYXG0FmnHkEHy5MhiGy7q4zCR2+ubTg==",
+ "dependencies": {
+ "@griffel/core": "^1.15.0",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8.0 <19.0.0"
+ }
+ },
+ "node_modules/@griffel/style-types": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@griffel/style-types/-/style-types-1.0.2.tgz",
+ "integrity": "sha512-ka/Tpl1WU8js88LObwB/4EvpgXzx/EEJfbHhAr4ZNt29hrQKgL93X1zSY6M/FRhMhWrGIawauWkZP6/y6w/WiQ==",
+ "dependencies": {
+ "csstype": "^3.1.2"
+ }
+ },
+ "node_modules/@humanwhocodes/config-array": {
+ "version": "0.11.11",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz",
+ "integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==",
+ "dev": true,
+ "dependencies": {
+ "@humanwhocodes/object-schema": "^1.2.1",
+ "debug": "^4.1.1",
+ "minimatch": "^3.0.5"
+ },
+ "engines": {
+ "node": ">=10.10.0"
+ }
+ },
+ "node_modules/@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+ "dev": true,
+ "engines": {
+ "node": ">=12.22"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@humanwhocodes/object-schema": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
+ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
+ "dev": true
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
+ "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/set-array": "^1.0.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
+ "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/set-array": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
+ "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.4.15",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
+ "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
+ "dev": true
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.19",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz",
+ "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/@microsoft/load-themed-styles": {
+ "version": "1.10.295",
+ "resolved": "https://registry.npmjs.org/@microsoft/load-themed-styles/-/load-themed-styles-1.10.295.tgz",
+ "integrity": "sha512-W+IzEBw8a6LOOfRJM02dTT7BDZijxm+Z7lhtOAz1+y9vQm1Kdz9jlAO+qCEKsfxtUOmKilW8DIRqFw2aUgKeGg=="
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true,
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@remix-run/router": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.9.0.tgz",
+ "integrity": "sha512-bV63itrKBC0zdT27qYm6SDZHlkXwFL1xMBuhkn+X7l0+IIhNaH5wuuvZKp6eKhCD4KFhujhfhCT1YxXW6esUIA==",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@swc/helpers": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.3.tgz",
+ "integrity": "sha512-FaruWX6KdudYloq1AHD/4nU+UsMTdNE8CKyrseXWEcgjDAbvkwJg2QGPAnfIJLIWsjZOSPLOAykK6fuYp4vp4A==",
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@types/babel__core": {
+ "version": "7.20.2",
+ "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.2.tgz",
+ "integrity": "sha512-pNpr1T1xLUc2l3xJKuPtsEky3ybxN3m4fJkknfIpTCTfIZCDW57oAg+EfCgIIp2rvCe0Wn++/FfodDS4YXxBwA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/parser": "^7.20.7",
+ "@babel/types": "^7.20.7",
+ "@types/babel__generator": "*",
+ "@types/babel__template": "*",
+ "@types/babel__traverse": "*"
+ }
+ },
+ "node_modules/@types/babel__generator": {
+ "version": "7.6.5",
+ "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.5.tgz",
+ "integrity": "sha512-h9yIuWbJKdOPLJTbmSpPzkF67e659PbQDba7ifWm5BJ8xTv+sDmS7rFmywkWOvXedGTivCdeGSIIX8WLcRTz8w==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__template": {
+ "version": "7.4.2",
+ "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.2.tgz",
+ "integrity": "sha512-/AVzPICMhMOMYoSx9MoKpGDKdBRsIXMNByh1PXSZoa+v6ZoLa8xxtsT/uLQ/NJm0XVAWl/BvId4MlDeXJaeIZQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/parser": "^7.1.0",
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__traverse": {
+ "version": "7.20.2",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.2.tgz",
+ "integrity": "sha512-ojlGK1Hsfce93J0+kn3H5R73elidKUaZonirN33GSmgTUMpzI/MIFfSpF3haANe3G1bEBS9/9/QEqwTzwqFsKw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.20.7"
+ }
+ },
+ "node_modules/@types/debug": {
+ "version": "4.1.12",
+ "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz",
+ "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==",
+ "dependencies": {
+ "@types/ms": "*"
+ }
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
+ "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw=="
+ },
+ "node_modules/@types/estree-jsx": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.3.tgz",
+ "integrity": "sha512-pvQ+TKeRHeiUGRhvYwRrQ/ISnohKkSJR14fT2yqyZ4e9K5vqc7hrtY2Y1Dw0ZwAzQ6DQsxsaCUuSIIi8v0Cq6w==",
+ "dependencies": {
+ "@types/estree": "*"
+ }
+ },
+ "node_modules/@types/hast": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.3.tgz",
+ "integrity": "sha512-2fYGlaDy/qyLlhidX42wAH0KBi2TCjKMH8CHmBXgRlJ3Y+OXTiqsPQ6IWarZKwF1JoUcAJdPogv1d4b0COTpmQ==",
+ "dependencies": {
+ "@types/unist": "*"
+ }
+ },
+ "node_modules/@types/json-schema": {
+ "version": "7.0.15",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+ "dev": true
+ },
+ "node_modules/@types/mdast": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.3.tgz",
+ "integrity": "sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==",
+ "dependencies": {
+ "@types/unist": "*"
+ }
+ },
+ "node_modules/@types/ms": {
+ "version": "0.7.34",
+ "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz",
+ "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g=="
+ },
+ "node_modules/@types/prop-types": {
+ "version": "15.7.8",
+ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.8.tgz",
+ "integrity": "sha512-kMpQpfZKSCBqltAJwskgePRaYRFukDkm1oItcAbC3gNELR20XIBcN9VRgg4+m8DKsTfkWeA4m4Imp4DDuWy7FQ=="
+ },
+ "node_modules/@types/react": {
+ "version": "18.2.27",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.27.tgz",
+ "integrity": "sha512-Wfv7B7FZiR2r3MIqbAlXoY1+tXm4bOqfz4oRr+nyXdBqapDBZ0l/IGcSlAfvxIHEEJjkPU0MYAc/BlFPOcrgLw==",
+ "dependencies": {
+ "@types/prop-types": "*",
+ "@types/scheduler": "*",
+ "csstype": "^3.0.2"
+ }
+ },
+ "node_modules/@types/react-dom": {
+ "version": "18.2.12",
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.12.tgz",
+ "integrity": "sha512-QWZuiA/7J/hPIGocXreCRbx7wyoeet9ooxfbSA+zbIWqyQEE7GMtRn4A37BdYyksnN+/NDnWgfxZH9UVGDw1hg==",
+ "dependencies": {
+ "@types/react": "*"
+ }
+ },
+ "node_modules/@types/scheduler": {
+ "version": "0.16.4",
+ "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.4.tgz",
+ "integrity": "sha512-2L9ifAGl7wmXwP4v3pN4p2FLhD0O1qsJpvKmNin5VA8+UvNVb447UDaAEV6UdrkA+m/Xs58U1RFps44x6TFsVQ=="
+ },
+ "node_modules/@types/semver": {
+ "version": "7.5.5",
+ "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.5.tgz",
+ "integrity": "sha512-+d+WYC1BxJ6yVOgUgzK8gWvp5qF8ssV5r4nsDcZWKRWcDQLQ619tvWAxJQYGgBrO1MnLJC7a5GtiYsAoQ47dJg==",
+ "dev": true
+ },
+ "node_modules/@types/unist": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz",
+ "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ=="
+ },
+ "node_modules/@typescript-eslint/eslint-plugin": {
+ "version": "6.10.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.10.0.tgz",
+ "integrity": "sha512-uoLj4g2OTL8rfUQVx2AFO1hp/zja1wABJq77P6IclQs6I/m9GLrm7jCdgzZkvWdDCQf1uEvoa8s8CupsgWQgVg==",
+ "dev": true,
+ "dependencies": {
+ "@eslint-community/regexpp": "^4.5.1",
+ "@typescript-eslint/scope-manager": "6.10.0",
+ "@typescript-eslint/type-utils": "6.10.0",
+ "@typescript-eslint/utils": "6.10.0",
+ "@typescript-eslint/visitor-keys": "6.10.0",
+ "debug": "^4.3.4",
+ "graphemer": "^1.4.0",
+ "ignore": "^5.2.4",
+ "natural-compare": "^1.4.0",
+ "semver": "^7.5.4",
+ "ts-api-utils": "^1.0.1"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha",
+ "eslint": "^7.0.0 || ^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/eslint-plugin/node_modules/lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dev": true,
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": {
+ "version": "7.5.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
+ "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+ "dev": true,
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@typescript-eslint/eslint-plugin/node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true
+ },
+ "node_modules/@typescript-eslint/parser": {
+ "version": "6.10.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.10.0.tgz",
+ "integrity": "sha512-+sZwIj+s+io9ozSxIWbNB5873OSdfeBEH/FR0re14WLI6BaKuSOnnwCJ2foUiu8uXf4dRp1UqHP0vrZ1zXGrog==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/scope-manager": "6.10.0",
+ "@typescript-eslint/types": "6.10.0",
+ "@typescript-eslint/typescript-estree": "6.10.0",
+ "@typescript-eslint/visitor-keys": "6.10.0",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^7.0.0 || ^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/scope-manager": {
+ "version": "6.10.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.10.0.tgz",
+ "integrity": "sha512-TN/plV7dzqqC2iPNf1KrxozDgZs53Gfgg5ZHyw8erd6jd5Ta/JIEcdCheXFt9b1NYb93a1wmIIVW/2gLkombDg==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/types": "6.10.0",
+ "@typescript-eslint/visitor-keys": "6.10.0"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/type-utils": {
+ "version": "6.10.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.10.0.tgz",
+ "integrity": "sha512-wYpPs3hgTFblMYwbYWPT3eZtaDOjbLyIYuqpwuLBBqhLiuvJ+9sEp2gNRJEtR5N/c9G1uTtQQL5AhV0fEPJYcg==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/typescript-estree": "6.10.0",
+ "@typescript-eslint/utils": "6.10.0",
+ "debug": "^4.3.4",
+ "ts-api-utils": "^1.0.1"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^7.0.0 || ^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/types": {
+ "version": "6.10.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.10.0.tgz",
+ "integrity": "sha512-36Fq1PWh9dusgo3vH7qmQAj5/AZqARky1Wi6WpINxB6SkQdY5vQoT2/7rW7uBIsPDcvvGCLi4r10p0OJ7ITAeg==",
+ "dev": true,
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree": {
+ "version": "6.10.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.10.0.tgz",
+ "integrity": "sha512-ek0Eyuy6P15LJVeghbWhSrBCj/vJpPXXR+EpaRZqou7achUWL8IdYnMSC5WHAeTWswYQuP2hAZgij/bC9fanBg==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/types": "6.10.0",
+ "@typescript-eslint/visitor-keys": "6.10.0",
+ "debug": "^4.3.4",
+ "globby": "^11.1.0",
+ "is-glob": "^4.0.3",
+ "semver": "^7.5.4",
+ "ts-api-utils": "^1.0.1"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dev": true,
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": {
+ "version": "7.5.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
+ "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+ "dev": true,
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true
+ },
+ "node_modules/@typescript-eslint/utils": {
+ "version": "6.10.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.10.0.tgz",
+ "integrity": "sha512-v+pJ1/RcVyRc0o4wAGux9x42RHmAjIGzPRo538Z8M1tVx6HOnoQBCX/NoadHQlZeC+QO2yr4nNSFWOoraZCAyg==",
+ "dev": true,
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.4.0",
+ "@types/json-schema": "^7.0.12",
+ "@types/semver": "^7.5.0",
+ "@typescript-eslint/scope-manager": "6.10.0",
+ "@typescript-eslint/types": "6.10.0",
+ "@typescript-eslint/typescript-estree": "6.10.0",
+ "semver": "^7.5.4"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/utils/node_modules/lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dev": true,
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@typescript-eslint/utils/node_modules/semver": {
+ "version": "7.5.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
+ "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+ "dev": true,
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@typescript-eslint/utils/node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true
+ },
+ "node_modules/@typescript-eslint/visitor-keys": {
+ "version": "6.10.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.10.0.tgz",
+ "integrity": "sha512-xMGluxQIEtOM7bqFCo+rCMh5fqI+ZxV5RUUOa29iVPz1OgCZrtc7rFnz5cLUazlkPKYqX+75iuDq7m0HQ48nCg==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/types": "6.10.0",
+ "eslint-visitor-keys": "^3.4.1"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@ungap/structured-clone": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz",
+ "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ=="
+ },
+ "node_modules/@vitejs/plugin-react": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.1.0.tgz",
+ "integrity": "sha512-rM0SqazU9iqPUraQ2JlIvReeaxOoRj6n+PzB1C0cBzIbd8qP336nC39/R9yPi3wVcah7E7j/kdU1uCUqMEU4OQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/core": "^7.22.20",
+ "@babel/plugin-transform-react-jsx-self": "^7.22.5",
+ "@babel/plugin-transform-react-jsx-source": "^7.22.5",
+ "@types/babel__core": "^7.20.2",
+ "react-refresh": "^0.14.0"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "vite": "^4.2.0"
+ }
+ },
+ "node_modules/acorn": {
+ "version": "8.10.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz",
+ "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==",
+ "dev": true,
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-jsx": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "dev": true,
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true
+ },
+ "node_modules/array-buffer-byte-length": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz",
+ "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "is-array-buffer": "^3.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array-includes": {
+ "version": "3.1.7",
+ "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz",
+ "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.2.0",
+ "es-abstract": "^1.22.1",
+ "get-intrinsic": "^1.2.1",
+ "is-string": "^1.0.7"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array-union": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/array.prototype.flat": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz",
+ "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.2.0",
+ "es-abstract": "^1.22.1",
+ "es-shim-unscopables": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flatmap": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz",
+ "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.2.0",
+ "es-abstract": "^1.22.1",
+ "es-shim-unscopables": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.tosorted": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.2.tgz",
+ "integrity": "sha512-HuQCHOlk1Weat5jzStICBCd83NxiIMwqDg/dHEsoefabn/hJRj5pVdWcPUSpRrwhwxZOsQassMpgN/xRYFBMIg==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.2.0",
+ "es-abstract": "^1.22.1",
+ "es-shim-unscopables": "^1.0.0",
+ "get-intrinsic": "^1.2.1"
+ }
+ },
+ "node_modules/arraybuffer.prototype.slice": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz",
+ "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==",
+ "dev": true,
+ "dependencies": {
+ "array-buffer-byte-length": "^1.0.0",
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.2.0",
+ "es-abstract": "^1.22.1",
+ "get-intrinsic": "^1.2.1",
+ "is-array-buffer": "^3.0.2",
+ "is-shared-array-buffer": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/asynciterator.prototype": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz",
+ "integrity": "sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg==",
+ "dev": true,
+ "dependencies": {
+ "has-symbols": "^1.0.3"
+ }
+ },
+ "node_modules/available-typed-arrays": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
+ "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/bail": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz",
+ "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "dependencies": {
+ "fill-range": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/browserslist": {
+ "version": "4.22.1",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz",
+ "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "dependencies": {
+ "caniuse-lite": "^1.0.30001541",
+ "electron-to-chromium": "^1.4.535",
+ "node-releases": "^2.0.13",
+ "update-browserslist-db": "^1.0.13"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/call-bind": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+ "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001547",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001547.tgz",
+ "integrity": "sha512-W7CrtIModMAxobGhz8iXmDfuJiiKg1WADMO/9x7/CLNin5cpSbuBjooyoIUVB5eyCc36QuTVlkVa1iB2S5+/eA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ]
+ },
+ "node_modules/ccount": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz",
+ "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/character-entities": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz",
+ "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/character-entities-html4": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz",
+ "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/character-entities-legacy": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz",
+ "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/character-reference-invalid": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz",
+ "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+ "dev": true
+ },
+ "node_modules/comma-separated-tokens": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz",
+ "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true
+ },
+ "node_modules/convert-source-map": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+ "dev": true
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/csstype": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
+ "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ=="
+ },
+ "node_modules/dayjs": {
+ "version": "1.11.10",
+ "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz",
+ "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ=="
+ },
+ "node_modules/debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/decode-named-character-reference": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz",
+ "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==",
+ "dependencies": {
+ "character-entities": "^2.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+ "dev": true
+ },
+ "node_modules/define-data-property": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.0.tgz",
+ "integrity": "sha512-UzGwzcjyv3OtAvolTj1GoyNYzfFR+iqbGjcnBEENZVCpM4/Ng1yhGNvS3lR/xDS74Tb2wGG9WzNSNIOS9UVb2g==",
+ "dev": true,
+ "dependencies": {
+ "get-intrinsic": "^1.2.1",
+ "gopd": "^1.0.1",
+ "has-property-descriptors": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/define-properties": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
+ "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
+ "dev": true,
+ "dependencies": {
+ "define-data-property": "^1.0.1",
+ "has-property-descriptors": "^1.0.0",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/dequal": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
+ "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/devlop": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz",
+ "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==",
+ "dependencies": {
+ "dequal": "^2.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/dir-glob": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+ "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+ "dev": true,
+ "dependencies": {
+ "path-type": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/doctrine": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+ "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+ "dev": true,
+ "dependencies": {
+ "esutils": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/dom-helpers": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz",
+ "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==",
+ "dependencies": {
+ "@babel/runtime": "^7.8.7",
+ "csstype": "^3.0.2"
+ }
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.4.548",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.548.tgz",
+ "integrity": "sha512-R77KD6mXv37DOyKLN/eW1rGS61N6yHOfapNSX9w+y9DdPG83l9Gkuv7qkCFZ4Ta4JPhrjgQfYbv4Y3TnM1Hi2Q==",
+ "dev": true
+ },
+ "node_modules/es-abstract": {
+ "version": "1.22.2",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.2.tgz",
+ "integrity": "sha512-YoxfFcDmhjOgWPWsV13+2RNjq1F6UQnfs+8TftwNqtzlmFzEXvlUwdrNrYeaizfjQzRMxkZ6ElWMOJIFKdVqwA==",
+ "dev": true,
+ "dependencies": {
+ "array-buffer-byte-length": "^1.0.0",
+ "arraybuffer.prototype.slice": "^1.0.2",
+ "available-typed-arrays": "^1.0.5",
+ "call-bind": "^1.0.2",
+ "es-set-tostringtag": "^2.0.1",
+ "es-to-primitive": "^1.2.1",
+ "function.prototype.name": "^1.1.6",
+ "get-intrinsic": "^1.2.1",
+ "get-symbol-description": "^1.0.0",
+ "globalthis": "^1.0.3",
+ "gopd": "^1.0.1",
+ "has": "^1.0.3",
+ "has-property-descriptors": "^1.0.0",
+ "has-proto": "^1.0.1",
+ "has-symbols": "^1.0.3",
+ "internal-slot": "^1.0.5",
+ "is-array-buffer": "^3.0.2",
+ "is-callable": "^1.2.7",
+ "is-negative-zero": "^2.0.2",
+ "is-regex": "^1.1.4",
+ "is-shared-array-buffer": "^1.0.2",
+ "is-string": "^1.0.7",
+ "is-typed-array": "^1.1.12",
+ "is-weakref": "^1.0.2",
+ "object-inspect": "^1.12.3",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.4",
+ "regexp.prototype.flags": "^1.5.1",
+ "safe-array-concat": "^1.0.1",
+ "safe-regex-test": "^1.0.0",
+ "string.prototype.trim": "^1.2.8",
+ "string.prototype.trimend": "^1.0.7",
+ "string.prototype.trimstart": "^1.0.7",
+ "typed-array-buffer": "^1.0.0",
+ "typed-array-byte-length": "^1.0.0",
+ "typed-array-byte-offset": "^1.0.0",
+ "typed-array-length": "^1.0.4",
+ "unbox-primitive": "^1.0.2",
+ "which-typed-array": "^1.1.11"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/es-iterator-helpers": {
+ "version": "1.0.15",
+ "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.15.tgz",
+ "integrity": "sha512-GhoY8uYqd6iwUl2kgjTm4CZAf6oo5mHK7BPqx3rKgx893YSsy0LGHV6gfqqQvZt/8xM8xeOnfXBCfqclMKkJ5g==",
+ "dev": true,
+ "dependencies": {
+ "asynciterator.prototype": "^1.0.0",
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.22.1",
+ "es-set-tostringtag": "^2.0.1",
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.2.1",
+ "globalthis": "^1.0.3",
+ "has-property-descriptors": "^1.0.0",
+ "has-proto": "^1.0.1",
+ "has-symbols": "^1.0.3",
+ "internal-slot": "^1.0.5",
+ "iterator.prototype": "^1.1.2",
+ "safe-array-concat": "^1.0.1"
+ }
+ },
+ "node_modules/es-set-tostringtag": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz",
+ "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==",
+ "dev": true,
+ "dependencies": {
+ "get-intrinsic": "^1.1.3",
+ "has": "^1.0.3",
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-shim-unscopables": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz",
+ "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==",
+ "dev": true,
+ "dependencies": {
+ "has": "^1.0.3"
+ }
+ },
+ "node_modules/es-to-primitive": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
+ "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
+ "dev": true,
+ "dependencies": {
+ "is-callable": "^1.1.4",
+ "is-date-object": "^1.0.1",
+ "is-symbol": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/esbuild": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
+ "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
+ "dev": true,
+ "hasInstallScript": true,
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "optionalDependencies": {
+ "@esbuild/android-arm": "0.18.20",
+ "@esbuild/android-arm64": "0.18.20",
+ "@esbuild/android-x64": "0.18.20",
+ "@esbuild/darwin-arm64": "0.18.20",
+ "@esbuild/darwin-x64": "0.18.20",
+ "@esbuild/freebsd-arm64": "0.18.20",
+ "@esbuild/freebsd-x64": "0.18.20",
+ "@esbuild/linux-arm": "0.18.20",
+ "@esbuild/linux-arm64": "0.18.20",
+ "@esbuild/linux-ia32": "0.18.20",
+ "@esbuild/linux-loong64": "0.18.20",
+ "@esbuild/linux-mips64el": "0.18.20",
+ "@esbuild/linux-ppc64": "0.18.20",
+ "@esbuild/linux-riscv64": "0.18.20",
+ "@esbuild/linux-s390x": "0.18.20",
+ "@esbuild/linux-x64": "0.18.20",
+ "@esbuild/netbsd-x64": "0.18.20",
+ "@esbuild/openbsd-x64": "0.18.20",
+ "@esbuild/sunos-x64": "0.18.20",
+ "@esbuild/win32-arm64": "0.18.20",
+ "@esbuild/win32-ia32": "0.18.20",
+ "@esbuild/win32-x64": "0.18.20"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/eslint": {
+ "version": "8.51.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.51.0.tgz",
+ "integrity": "sha512-2WuxRZBrlwnXi+/vFSJyjMqrNjtJqiasMzehF0shoLaW7DzS3/9Yvrmq5JiT66+pNjiX4UBnLDiKHcWAr/OInA==",
+ "dev": true,
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.2.0",
+ "@eslint-community/regexpp": "^4.6.1",
+ "@eslint/eslintrc": "^2.1.2",
+ "@eslint/js": "8.51.0",
+ "@humanwhocodes/config-array": "^0.11.11",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@nodelib/fs.walk": "^1.2.8",
+ "ajv": "^6.12.4",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.2",
+ "debug": "^4.3.2",
+ "doctrine": "^3.0.0",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^7.2.2",
+ "eslint-visitor-keys": "^3.4.3",
+ "espree": "^9.6.1",
+ "esquery": "^1.4.2",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^6.0.1",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "globals": "^13.19.0",
+ "graphemer": "^1.4.0",
+ "ignore": "^5.2.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "is-path-inside": "^3.0.3",
+ "js-yaml": "^4.1.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "levn": "^0.4.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.1.2",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.3",
+ "strip-ansi": "^6.0.1",
+ "text-table": "^0.2.0"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-plugin-react": {
+ "version": "7.33.2",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.33.2.tgz",
+ "integrity": "sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==",
+ "dev": true,
+ "dependencies": {
+ "array-includes": "^3.1.6",
+ "array.prototype.flatmap": "^1.3.1",
+ "array.prototype.tosorted": "^1.1.1",
+ "doctrine": "^2.1.0",
+ "es-iterator-helpers": "^1.0.12",
+ "estraverse": "^5.3.0",
+ "jsx-ast-utils": "^2.4.1 || ^3.0.0",
+ "minimatch": "^3.1.2",
+ "object.entries": "^1.1.6",
+ "object.fromentries": "^2.0.6",
+ "object.hasown": "^1.1.2",
+ "object.values": "^1.1.6",
+ "prop-types": "^15.8.1",
+ "resolve": "^2.0.0-next.4",
+ "semver": "^6.3.1",
+ "string.prototype.matchall": "^4.0.8"
+ },
+ "engines": {
+ "node": ">=4"
+ },
+ "peerDependencies": {
+ "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8"
+ }
+ },
+ "node_modules/eslint-plugin-react-hooks": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz",
+ "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0"
+ }
+ },
+ "node_modules/eslint-plugin-react-refresh": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.3.tgz",
+ "integrity": "sha512-Hh0wv8bUNY877+sI0BlCUlsS0TYYQqvzEwJsJJPM2WF4RnTStSnSR3zdJYa2nPOJgg3UghXi54lVyMSmpCalzA==",
+ "dev": true,
+ "peerDependencies": {
+ "eslint": ">=7"
+ }
+ },
+ "node_modules/eslint-plugin-react/node_modules/doctrine": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
+ "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
+ "dev": true,
+ "dependencies": {
+ "esutils": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "7.2.2",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
+ "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
+ "dev": true,
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "dev": true,
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/eslint/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/eslint/node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/eslint/node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "node_modules/eslint/node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint/node_modules/globals": {
+ "version": "13.23.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz",
+ "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==",
+ "dev": true,
+ "dependencies": {
+ "type-fest": "^0.20.2"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/eslint/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/espree": {
+ "version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
+ "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
+ "dev": true,
+ "dependencies": {
+ "acorn": "^8.9.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^3.4.1"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/esquery": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
+ "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==",
+ "dev": true,
+ "dependencies": {
+ "estraverse": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estree-util-is-identifier-name": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz",
+ "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/extend": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "dev": true
+ },
+ "node_modules/fast-glob": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
+ "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
+ "dev": true,
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.4"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/fast-glob/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true
+ },
+ "node_modules/fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+ "dev": true
+ },
+ "node_modules/fastq": {
+ "version": "1.15.0",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
+ "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==",
+ "dev": true,
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/file-entry-cache": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
+ "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
+ "dev": true,
+ "dependencies": {
+ "flat-cache": "^3.0.4"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/flat-cache": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.1.tgz",
+ "integrity": "sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q==",
+ "dev": true,
+ "dependencies": {
+ "flatted": "^3.2.9",
+ "keyv": "^4.5.3",
+ "rimraf": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/flatted": {
+ "version": "3.2.9",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz",
+ "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==",
+ "dev": true
+ },
+ "node_modules/for-each": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
+ "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
+ "dev": true,
+ "dependencies": {
+ "is-callable": "^1.1.3"
+ }
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+ "dev": true
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+ "dev": true
+ },
+ "node_modules/function.prototype.name": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz",
+ "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.2.0",
+ "es-abstract": "^1.22.1",
+ "functions-have-names": "^1.2.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/functions-have-names": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
+ "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/gensync": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz",
+ "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-proto": "^1.0.1",
+ "has-symbols": "^1.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-symbol-description": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz",
+ "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "get-intrinsic": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "dev": true,
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/globalthis": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz",
+ "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==",
+ "dev": true,
+ "dependencies": {
+ "define-properties": "^1.1.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/globby": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
+ "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
+ "dev": true,
+ "dependencies": {
+ "array-union": "^2.1.0",
+ "dir-glob": "^3.0.1",
+ "fast-glob": "^3.2.9",
+ "ignore": "^5.2.0",
+ "merge2": "^1.4.1",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/gopd": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
+ "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
+ "dev": true,
+ "dependencies": {
+ "get-intrinsic": "^1.1.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/graphemer": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
+ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
+ "dev": true
+ },
+ "node_modules/has": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz",
+ "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/has-bigints": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
+ "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/has-property-descriptors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz",
+ "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==",
+ "dev": true,
+ "dependencies": {
+ "get-intrinsic": "^1.1.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
+ "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-symbols": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
+ "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-tostringtag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
+ "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
+ "dev": true,
+ "dependencies": {
+ "has-symbols": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hast-util-to-jsx-runtime": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.0.tgz",
+ "integrity": "sha512-H/y0+IWPdsLLS738P8tDnrQ8Z+dj12zQQ6WC11TIM21C8WFVoIxcqWXf2H3hiTVZjF1AWqoimGwrTWecWrnmRQ==",
+ "dependencies": {
+ "@types/estree": "^1.0.0",
+ "@types/hast": "^3.0.0",
+ "@types/unist": "^3.0.0",
+ "comma-separated-tokens": "^2.0.0",
+ "devlop": "^1.0.0",
+ "estree-util-is-identifier-name": "^3.0.0",
+ "hast-util-whitespace": "^3.0.0",
+ "mdast-util-mdx-expression": "^2.0.0",
+ "mdast-util-mdx-jsx": "^3.0.0",
+ "mdast-util-mdxjs-esm": "^2.0.0",
+ "property-information": "^6.0.0",
+ "space-separated-tokens": "^2.0.0",
+ "style-to-object": "^1.0.0",
+ "unist-util-position": "^5.0.0",
+ "vfile-message": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/hast-util-whitespace": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz",
+ "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==",
+ "dependencies": {
+ "@types/hast": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/html-url-attributes": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/html-url-attributes/-/html-url-attributes-3.0.0.tgz",
+ "integrity": "sha512-/sXbVCWayk6GDVg3ctOX6nxaVj7So40FcFAnWlWGNAB1LpYKcV5Cd10APjPjW80O7zYW2MsjBV4zZ7IZO5fVow==",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/ignore": {
+ "version": "5.2.4",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
+ "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
+ "dev": true,
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/immediate": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
+ "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ=="
+ },
+ "node_modules/import-fresh": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
+ "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
+ "dev": true,
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "dev": true,
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true
+ },
+ "node_modules/inline-style-parser": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.2.tgz",
+ "integrity": "sha512-EcKzdTHVe8wFVOGEYXiW9WmJXPjqi1T+234YpJr98RiFYKHV3cdy1+3mkTE+KHTHxFFLH51SfaGOoUdW+v7ViQ=="
+ },
+ "node_modules/internal-slot": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz",
+ "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==",
+ "dev": true,
+ "dependencies": {
+ "get-intrinsic": "^1.2.0",
+ "has": "^1.0.3",
+ "side-channel": "^1.0.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/is-alphabetical": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz",
+ "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/is-alphanumerical": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz",
+ "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==",
+ "dependencies": {
+ "is-alphabetical": "^2.0.0",
+ "is-decimal": "^2.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/is-array-buffer": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz",
+ "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "get-intrinsic": "^1.2.0",
+ "is-typed-array": "^1.1.10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-async-function": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz",
+ "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==",
+ "dev": true,
+ "dependencies": {
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-bigint": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
+ "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==",
+ "dev": true,
+ "dependencies": {
+ "has-bigints": "^1.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-boolean-object": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
+ "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-callable": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
+ "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.13.0",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz",
+ "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==",
+ "dev": true,
+ "dependencies": {
+ "has": "^1.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-date-object": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
+ "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
+ "dev": true,
+ "dependencies": {
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-decimal": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz",
+ "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-finalizationregistry": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz",
+ "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-generator-function": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz",
+ "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==",
+ "dev": true,
+ "dependencies": {
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-hexadecimal": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz",
+ "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/is-map": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz",
+ "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-negative-zero": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
+ "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-number-object": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz",
+ "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==",
+ "dev": true,
+ "dependencies": {
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-path-inside": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
+ "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-plain-obj": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz",
+ "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-regex": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
+ "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-set": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz",
+ "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-shared-array-buffer": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz",
+ "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-string": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
+ "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==",
+ "dev": true,
+ "dependencies": {
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-symbol": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz",
+ "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==",
+ "dev": true,
+ "dependencies": {
+ "has-symbols": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-typed-array": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz",
+ "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==",
+ "dev": true,
+ "dependencies": {
+ "which-typed-array": "^1.1.11"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakmap": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz",
+ "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakref": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
+ "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakset": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz",
+ "integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "get-intrinsic": "^1.1.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/isarray": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
+ "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
+ "dev": true
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true
+ },
+ "node_modules/iterator.prototype": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz",
+ "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==",
+ "dev": true,
+ "dependencies": {
+ "define-properties": "^1.2.1",
+ "get-intrinsic": "^1.2.1",
+ "has-symbols": "^1.0.3",
+ "reflect.getprototypeof": "^1.0.4",
+ "set-function-name": "^2.0.1"
+ }
+ },
+ "node_modules/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "dev": true,
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/jsesc": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
+ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+ "dev": true,
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/json-buffer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
+ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
+ "dev": true
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true
+ },
+ "node_modules/json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
+ "dev": true
+ },
+ "node_modules/json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "dev": true,
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/jsx-ast-utils": {
+ "version": "3.3.5",
+ "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz",
+ "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==",
+ "dev": true,
+ "dependencies": {
+ "array-includes": "^3.1.6",
+ "array.prototype.flat": "^1.3.1",
+ "object.assign": "^4.1.4",
+ "object.values": "^1.1.6"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/keyborg": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/keyborg/-/keyborg-2.1.0.tgz",
+ "integrity": "sha512-0+v3/GIYG6gClwBOXrHet31n1UJW49xbKgVPUu6we41aq9tAmMosVXEdctZxsQdebyxtrcxVTkvHjBD1XPOHwg=="
+ },
+ "node_modules/keyv": {
+ "version": "4.5.4",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
+ "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
+ "dev": true,
+ "dependencies": {
+ "json-buffer": "3.0.1"
+ }
+ },
+ "node_modules/levn": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+ "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+ "dev": true,
+ "dependencies": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/lie": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz",
+ "integrity": "sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==",
+ "dependencies": {
+ "immediate": "~3.0.5"
+ }
+ },
+ "node_modules/localforage": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/localforage/-/localforage-1.10.0.tgz",
+ "integrity": "sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==",
+ "dependencies": {
+ "lie": "3.1.1"
+ }
+ },
+ "node_modules/localstorage-slim": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/localstorage-slim/-/localstorage-slim-2.7.0.tgz",
+ "integrity": "sha512-velxCZhb0mODaD9noe4pu3+OYnMKC66itqDqHMRsVpXKAJYU2+cUX09KRxoZ/nlVwitVgjlG2BZSEaP6RPJmgw=="
+ },
+ "node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+ "dev": true
+ },
+ "node_modules/longest-streak": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz",
+ "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/loose-envify": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+ "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+ "dependencies": {
+ "js-tokens": "^3.0.0 || ^4.0.0"
+ },
+ "bin": {
+ "loose-envify": "cli.js"
+ }
+ },
+ "node_modules/lru-cache": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "dev": true,
+ "dependencies": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "node_modules/match-sorter": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/match-sorter/-/match-sorter-6.3.1.tgz",
+ "integrity": "sha512-mxybbo3pPNuA+ZuCUhm5bwNkXrJTbsk5VWbR5wiwz/GC6LIiegBGn2w3O08UG/jdbYLinw51fSQ5xNU1U3MgBw==",
+ "dependencies": {
+ "@babel/runtime": "^7.12.5",
+ "remove-accents": "0.4.2"
+ }
+ },
+ "node_modules/mdast-util-from-markdown": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.0.tgz",
+ "integrity": "sha512-n7MTOr/z+8NAX/wmhhDji8O3bRvPTV/U0oTCaZJkjhPSKTPhS3xufVhKGF8s1pJ7Ox4QgoIU7KHseh09S+9rTA==",
+ "dependencies": {
+ "@types/mdast": "^4.0.0",
+ "@types/unist": "^3.0.0",
+ "decode-named-character-reference": "^1.0.0",
+ "devlop": "^1.0.0",
+ "mdast-util-to-string": "^4.0.0",
+ "micromark": "^4.0.0",
+ "micromark-util-decode-numeric-character-reference": "^2.0.0",
+ "micromark-util-decode-string": "^2.0.0",
+ "micromark-util-normalize-identifier": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0",
+ "unist-util-stringify-position": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-mdx-expression": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.0.tgz",
+ "integrity": "sha512-fGCu8eWdKUKNu5mohVGkhBXCXGnOTLuFqOvGMvdikr+J1w7lDJgxThOKpwRWzzbyXAU2hhSwsmssOY4yTokluw==",
+ "dependencies": {
+ "@types/estree-jsx": "^1.0.0",
+ "@types/hast": "^3.0.0",
+ "@types/mdast": "^4.0.0",
+ "devlop": "^1.0.0",
+ "mdast-util-from-markdown": "^2.0.0",
+ "mdast-util-to-markdown": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-mdx-jsx": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.0.0.tgz",
+ "integrity": "sha512-XZuPPzQNBPAlaqsTTgRrcJnyFbSOBovSadFgbFu8SnuNgm+6Bdx1K+IWoitsmj6Lq6MNtI+ytOqwN70n//NaBA==",
+ "dependencies": {
+ "@types/estree-jsx": "^1.0.0",
+ "@types/hast": "^3.0.0",
+ "@types/mdast": "^4.0.0",
+ "@types/unist": "^3.0.0",
+ "ccount": "^2.0.0",
+ "devlop": "^1.1.0",
+ "mdast-util-from-markdown": "^2.0.0",
+ "mdast-util-to-markdown": "^2.0.0",
+ "parse-entities": "^4.0.0",
+ "stringify-entities": "^4.0.0",
+ "unist-util-remove-position": "^5.0.0",
+ "unist-util-stringify-position": "^4.0.0",
+ "vfile-message": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-mdxjs-esm": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz",
+ "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==",
+ "dependencies": {
+ "@types/estree-jsx": "^1.0.0",
+ "@types/hast": "^3.0.0",
+ "@types/mdast": "^4.0.0",
+ "devlop": "^1.0.0",
+ "mdast-util-from-markdown": "^2.0.0",
+ "mdast-util-to-markdown": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-phrasing": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.0.0.tgz",
+ "integrity": "sha512-xadSsJayQIucJ9n053dfQwVu1kuXg7jCTdYsMK8rqzKZh52nLfSH/k0sAxE0u+pj/zKZX+o5wB+ML5mRayOxFA==",
+ "dependencies": {
+ "@types/mdast": "^4.0.0",
+ "unist-util-is": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-to-hast": {
+ "version": "13.0.2",
+ "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.0.2.tgz",
+ "integrity": "sha512-U5I+500EOOw9e3ZrclN3Is3fRpw8c19SMyNZlZ2IS+7vLsNzb2Om11VpIVOR+/0137GhZsFEF6YiKD5+0Hr2Og==",
+ "dependencies": {
+ "@types/hast": "^3.0.0",
+ "@types/mdast": "^4.0.0",
+ "@ungap/structured-clone": "^1.0.0",
+ "devlop": "^1.0.0",
+ "micromark-util-sanitize-uri": "^2.0.0",
+ "trim-lines": "^3.0.0",
+ "unist-util-position": "^5.0.0",
+ "unist-util-visit": "^5.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-to-markdown": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.0.tgz",
+ "integrity": "sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==",
+ "dependencies": {
+ "@types/mdast": "^4.0.0",
+ "@types/unist": "^3.0.0",
+ "longest-streak": "^3.0.0",
+ "mdast-util-phrasing": "^4.0.0",
+ "mdast-util-to-string": "^4.0.0",
+ "micromark-util-decode-string": "^2.0.0",
+ "unist-util-visit": "^5.0.0",
+ "zwitch": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-to-string": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz",
+ "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==",
+ "dependencies": {
+ "@types/mdast": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/micromark": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.0.tgz",
+ "integrity": "sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "dependencies": {
+ "@types/debug": "^4.0.0",
+ "debug": "^4.0.0",
+ "decode-named-character-reference": "^1.0.0",
+ "devlop": "^1.0.0",
+ "micromark-core-commonmark": "^2.0.0",
+ "micromark-factory-space": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-chunked": "^2.0.0",
+ "micromark-util-combine-extensions": "^2.0.0",
+ "micromark-util-decode-numeric-character-reference": "^2.0.0",
+ "micromark-util-encode": "^2.0.0",
+ "micromark-util-normalize-identifier": "^2.0.0",
+ "micromark-util-resolve-all": "^2.0.0",
+ "micromark-util-sanitize-uri": "^2.0.0",
+ "micromark-util-subtokenize": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-core-commonmark": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.0.tgz",
+ "integrity": "sha512-jThOz/pVmAYUtkroV3D5c1osFXAMv9e0ypGDOIZuCeAe91/sD6BoE2Sjzt30yuXtwOYUmySOhMas/PVyh02itA==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "dependencies": {
+ "decode-named-character-reference": "^1.0.0",
+ "devlop": "^1.0.0",
+ "micromark-factory-destination": "^2.0.0",
+ "micromark-factory-label": "^2.0.0",
+ "micromark-factory-space": "^2.0.0",
+ "micromark-factory-title": "^2.0.0",
+ "micromark-factory-whitespace": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-chunked": "^2.0.0",
+ "micromark-util-classify-character": "^2.0.0",
+ "micromark-util-html-tag-name": "^2.0.0",
+ "micromark-util-normalize-identifier": "^2.0.0",
+ "micromark-util-resolve-all": "^2.0.0",
+ "micromark-util-subtokenize": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-factory-destination": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz",
+ "integrity": "sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "dependencies": {
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-factory-label": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz",
+ "integrity": "sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "dependencies": {
+ "devlop": "^1.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-factory-space": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz",
+ "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "dependencies": {
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-factory-title": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz",
+ "integrity": "sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "dependencies": {
+ "micromark-factory-space": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-factory-whitespace": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz",
+ "integrity": "sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "dependencies": {
+ "micromark-factory-space": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-character": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz",
+ "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "dependencies": {
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-chunked": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz",
+ "integrity": "sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "dependencies": {
+ "micromark-util-symbol": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-classify-character": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz",
+ "integrity": "sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "dependencies": {
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-combine-extensions": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz",
+ "integrity": "sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "dependencies": {
+ "micromark-util-chunked": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-decode-numeric-character-reference": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.1.tgz",
+ "integrity": "sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "dependencies": {
+ "micromark-util-symbol": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-decode-string": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz",
+ "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "dependencies": {
+ "decode-named-character-reference": "^1.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-decode-numeric-character-reference": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-encode": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz",
+ "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ]
+ },
+ "node_modules/micromark-util-html-tag-name": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz",
+ "integrity": "sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ]
+ },
+ "node_modules/micromark-util-normalize-identifier": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz",
+ "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "dependencies": {
+ "micromark-util-symbol": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-resolve-all": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz",
+ "integrity": "sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "dependencies": {
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-sanitize-uri": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz",
+ "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "dependencies": {
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-encode": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-subtokenize": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.0.tgz",
+ "integrity": "sha512-vc93L1t+gpR3p8jxeVdaYlbV2jTYteDje19rNSS/H5dlhxUYll5Fy6vJ2cDwP8RnsXi818yGty1ayP55y3W6fg==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "dependencies": {
+ "devlop": "^1.0.0",
+ "micromark-util-chunked": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-symbol": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz",
+ "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ]
+ },
+ "node_modules/micromark-util-types": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz",
+ "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ]
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
+ "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
+ "dev": true,
+ "dependencies": {
+ "braces": "^3.0.2",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
+ "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+ "dev": true
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.13",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz",
+ "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==",
+ "dev": true
+ },
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-inspect": {
+ "version": "1.12.3",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz",
+ "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/object-path": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.6.0.tgz",
+ "integrity": "sha512-fxrwsCFi3/p+LeLOAwo/wyRMODZxdGBtUlWRzsEpsUVrisZbEfZ21arxLGfaWfcnqb8oHPNihIb4XPE8CQPN5A==",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/object.assign": {
+ "version": "4.1.4",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz",
+ "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "has-symbols": "^1.0.3",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.entries": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.7.tgz",
+ "integrity": "sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.2.0",
+ "es-abstract": "^1.22.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/object.fromentries": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz",
+ "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.2.0",
+ "es-abstract": "^1.22.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.hasown": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.3.tgz",
+ "integrity": "sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA==",
+ "dev": true,
+ "dependencies": {
+ "define-properties": "^1.2.0",
+ "es-abstract": "^1.22.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.values": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz",
+ "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.2.0",
+ "es-abstract": "^1.22.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dev": true,
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/optionator": {
+ "version": "0.9.3",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz",
+ "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==",
+ "dev": true,
+ "dependencies": {
+ "@aashutoshrathi/word-wrap": "^1.2.3",
+ "deep-is": "^0.1.3",
+ "fast-levenshtein": "^2.0.6",
+ "levn": "^0.4.1",
+ "prelude-ls": "^1.2.1",
+ "type-check": "^0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "dependencies": {
+ "callsites": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/parse-entities": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.1.tgz",
+ "integrity": "sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==",
+ "dependencies": {
+ "@types/unist": "^2.0.0",
+ "character-entities": "^2.0.0",
+ "character-entities-legacy": "^3.0.0",
+ "character-reference-invalid": "^2.0.0",
+ "decode-named-character-reference": "^1.0.0",
+ "is-alphanumerical": "^2.0.0",
+ "is-decimal": "^2.0.0",
+ "is-hexadecimal": "^2.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/parse-entities/node_modules/@types/unist": {
+ "version": "2.0.10",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz",
+ "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA=="
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true
+ },
+ "node_modules/path-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/picocolors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
+ "dev": true
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/postcss": {
+ "version": "8.4.31",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
+ "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "dependencies": {
+ "nanoid": "^3.3.6",
+ "picocolors": "^1.0.0",
+ "source-map-js": "^1.0.2"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/prelude-ls": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/prop-types": {
+ "version": "15.8.1",
+ "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
+ "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
+ "dependencies": {
+ "loose-envify": "^1.4.0",
+ "object-assign": "^4.1.1",
+ "react-is": "^16.13.1"
+ }
+ },
+ "node_modules/property-information": {
+ "version": "6.4.0",
+ "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.4.0.tgz",
+ "integrity": "sha512-9t5qARVofg2xQqKtytzt+lZ4d1Qvj8t5B8fEwXK6qOfgRLgH/b13QlgEyDh033NOS31nXeFbYv7CLUDG1CeifQ==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
+ "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/react": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
+ "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-dom": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
+ "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==",
+ "dependencies": {
+ "loose-envify": "^1.1.0",
+ "scheduler": "^0.23.0"
+ },
+ "peerDependencies": {
+ "react": "^18.2.0"
+ }
+ },
+ "node_modules/react-dom/node_modules/scheduler": {
+ "version": "0.23.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
+ "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ }
+ },
+ "node_modules/react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
+ },
+ "node_modules/react-markdown": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-9.0.1.tgz",
+ "integrity": "sha512-186Gw/vF1uRkydbsOIkcGXw7aHq0sZOCRFFjGrr7b9+nVZg4UfA4enXCaxm4fUzecU38sWfrNDitGhshuU7rdg==",
+ "dependencies": {
+ "@types/hast": "^3.0.0",
+ "devlop": "^1.0.0",
+ "hast-util-to-jsx-runtime": "^2.0.0",
+ "html-url-attributes": "^3.0.0",
+ "mdast-util-to-hast": "^13.0.0",
+ "remark-parse": "^11.0.0",
+ "remark-rehype": "^11.0.0",
+ "unified": "^11.0.0",
+ "unist-util-visit": "^5.0.0",
+ "vfile": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ },
+ "peerDependencies": {
+ "@types/react": ">=18",
+ "react": ">=18"
+ }
+ },
+ "node_modules/react-refresh": {
+ "version": "0.14.0",
+ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz",
+ "integrity": "sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-router": {
+ "version": "6.16.0",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.16.0.tgz",
+ "integrity": "sha512-VT4Mmc4jj5YyjpOi5jOf0I+TYzGpvzERy4ckNSvSh2RArv8LLoCxlsZ2D+tc7zgjxcY34oTz2hZaeX5RVprKqA==",
+ "dependencies": {
+ "@remix-run/router": "1.9.0"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8"
+ }
+ },
+ "node_modules/react-router-dom": {
+ "version": "6.16.0",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.16.0.tgz",
+ "integrity": "sha512-aTfBLv3mk/gaKLxgRDUPbPw+s4Y/O+ma3rEN1u8EgEpLpPe6gNjIsWt9rxushMHHMb7mSwxRGdGlGdvmFsyPIg==",
+ "dependencies": {
+ "@remix-run/router": "1.9.0",
+ "react-router": "6.16.0"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8",
+ "react-dom": ">=16.8"
+ }
+ },
+ "node_modules/react-transition-group": {
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
+ "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==",
+ "dependencies": {
+ "@babel/runtime": "^7.5.5",
+ "dom-helpers": "^5.0.1",
+ "loose-envify": "^1.4.0",
+ "prop-types": "^15.6.2"
+ },
+ "peerDependencies": {
+ "react": ">=16.6.0",
+ "react-dom": ">=16.6.0"
+ }
+ },
+ "node_modules/reflect.getprototypeof": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz",
+ "integrity": "sha512-ECkTw8TmJwW60lOTR+ZkODISW6RQ8+2CL3COqtiJKLd6MmB45hN51HprHFziKLGkAuTGQhBb91V8cy+KHlaCjw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.2.0",
+ "es-abstract": "^1.22.1",
+ "get-intrinsic": "^1.2.1",
+ "globalthis": "^1.0.3",
+ "which-builtin-type": "^1.1.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/regenerator-runtime": {
+ "version": "0.14.0",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz",
+ "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA=="
+ },
+ "node_modules/regexp.prototype.flags": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz",
+ "integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.2.0",
+ "set-function-name": "^2.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/remark-parse": {
+ "version": "11.0.0",
+ "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz",
+ "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==",
+ "dependencies": {
+ "@types/mdast": "^4.0.0",
+ "mdast-util-from-markdown": "^2.0.0",
+ "micromark-util-types": "^2.0.0",
+ "unified": "^11.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/remark-rehype": {
+ "version": "11.0.0",
+ "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.0.0.tgz",
+ "integrity": "sha512-vx8x2MDMcxuE4lBmQ46zYUDfcFMmvg80WYX+UNLeG6ixjdCCLcw1lrgAukwBTuOFsS78eoAedHGn9sNM0w7TPw==",
+ "dependencies": {
+ "@types/hast": "^3.0.0",
+ "@types/mdast": "^4.0.0",
+ "mdast-util-to-hast": "^13.0.0",
+ "unified": "^11.0.0",
+ "vfile": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/remove-accents": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.4.2.tgz",
+ "integrity": "sha512-7pXIJqJOq5tFgG1A2Zxti3Ht8jJF337m4sowbuHsW30ZnkQFnDzy9qBNhgzX8ZLW4+UBcXiiR7SwR6pokHsxiA=="
+ },
+ "node_modules/resolve": {
+ "version": "2.0.0-next.4",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz",
+ "integrity": "sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==",
+ "dev": true,
+ "dependencies": {
+ "is-core-module": "^2.9.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/reusify": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+ "dev": true,
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "dev": true,
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/rollup": {
+ "version": "3.29.4",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz",
+ "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==",
+ "dev": true,
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=14.18.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/rtl-css-js": {
+ "version": "1.16.1",
+ "resolved": "https://registry.npmjs.org/rtl-css-js/-/rtl-css-js-1.16.1.tgz",
+ "integrity": "sha512-lRQgou1mu19e+Ya0LsTvKrVJ5TYUbqCVPAiImX3UfLTenarvPUl1QFdvu5Z3PYmHT9RCcwIfbjRQBntExyj3Zg==",
+ "dependencies": {
+ "@babel/runtime": "^7.1.2"
+ }
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "node_modules/safe-array-concat": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz",
+ "integrity": "sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "get-intrinsic": "^1.2.1",
+ "has-symbols": "^1.0.3",
+ "isarray": "^2.0.5"
+ },
+ "engines": {
+ "node": ">=0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/safe-regex-test": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz",
+ "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "get-intrinsic": "^1.1.3",
+ "is-regex": "^1.1.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/scheduler": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz",
+ "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==",
+ "peer": true,
+ "dependencies": {
+ "loose-envify": "^1.1.0",
+ "object-assign": "^4.1.1"
+ }
+ },
+ "node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/set-function-name": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz",
+ "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==",
+ "dev": true,
+ "dependencies": {
+ "define-data-property": "^1.0.1",
+ "functions-have-names": "^1.2.3",
+ "has-property-descriptors": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/side-channel": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
+ "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.0",
+ "get-intrinsic": "^1.0.2",
+ "object-inspect": "^1.9.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/sort-by": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/sort-by/-/sort-by-1.2.0.tgz",
+ "integrity": "sha512-aRyW65r3xMnf4nxJRluCg0H/woJpksU1dQxRtXYzau30sNBOmf5HACpDd9MZDhKh7ALQ5FgSOfMPwZEtUmMqcg==",
+ "dependencies": {
+ "object-path": "0.6.0"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
+ "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/space-separated-tokens": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz",
+ "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/string.prototype.matchall": {
+ "version": "4.0.10",
+ "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz",
+ "integrity": "sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.2.0",
+ "es-abstract": "^1.22.1",
+ "get-intrinsic": "^1.2.1",
+ "has-symbols": "^1.0.3",
+ "internal-slot": "^1.0.5",
+ "regexp.prototype.flags": "^1.5.0",
+ "set-function-name": "^2.0.0",
+ "side-channel": "^1.0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trim": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz",
+ "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.2.0",
+ "es-abstract": "^1.22.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trimend": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz",
+ "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.2.0",
+ "es-abstract": "^1.22.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trimstart": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz",
+ "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.2.0",
+ "es-abstract": "^1.22.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/stringify-entities": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.3.tgz",
+ "integrity": "sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g==",
+ "dependencies": {
+ "character-entities-html4": "^2.0.0",
+ "character-entities-legacy": "^3.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/style-to-object": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.5.tgz",
+ "integrity": "sha512-rDRwHtoDD3UMMrmZ6BzOW0naTjMsVZLIjsGleSKS/0Oz+cgCfAPRspaqJuE8rDzpKha/nEvnM0IF4seEAZUTKQ==",
+ "dependencies": {
+ "inline-style-parser": "0.2.2"
+ }
+ },
+ "node_modules/stylis": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.0.tgz",
+ "integrity": "sha512-E87pIogpwUsUwXw7dNyU4QDjdgVMy52m+XEOPEKUn161cCzWjjhPSQhByfd1CcNvrOLnXQ6OnnZDwnJrz/Z4YQ=="
+ },
+ "node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/tabster": {
+ "version": "4.9.0",
+ "resolved": "https://registry.npmjs.org/tabster/-/tabster-4.9.0.tgz",
+ "integrity": "sha512-wcXpMQxLA7OFcL4ci6Spsv0C1S26HtCD4904XTW78mQ2iPsKyo+SdjBUZ4SHhNMpa1y4P1cByc6dPJ0n+9yVzA==",
+ "dependencies": {
+ "keyborg": "^2.0.0",
+ "tslib": "^2.3.1"
+ }
+ },
+ "node_modules/text-table": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
+ "dev": true
+ },
+ "node_modules/to-fast-properties": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
+ "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/trim-lines": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz",
+ "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/trough": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/trough/-/trough-2.1.0.tgz",
+ "integrity": "sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/ts-api-utils": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz",
+ "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==",
+ "dev": true,
+ "engines": {
+ "node": ">=16.13.0"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.2.0"
+ }
+ },
+ "node_modules/tslib": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
+ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
+ },
+ "node_modules/type-check": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+ "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+ "dev": true,
+ "dependencies": {
+ "prelude-ls": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/type-fest": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
+ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/typed-array-buffer": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz",
+ "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "get-intrinsic": "^1.2.1",
+ "is-typed-array": "^1.1.10"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/typed-array-byte-length": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz",
+ "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "for-each": "^0.3.3",
+ "has-proto": "^1.0.1",
+ "is-typed-array": "^1.1.10"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typed-array-byte-offset": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz",
+ "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==",
+ "dev": true,
+ "dependencies": {
+ "available-typed-arrays": "^1.0.5",
+ "call-bind": "^1.0.2",
+ "for-each": "^0.3.3",
+ "has-proto": "^1.0.1",
+ "is-typed-array": "^1.1.10"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typed-array-length": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz",
+ "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "for-each": "^0.3.3",
+ "is-typed-array": "^1.1.9"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typescript": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
+ "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==",
+ "dev": true,
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/unbox-primitive": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
+ "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "has-bigints": "^1.0.2",
+ "has-symbols": "^1.0.3",
+ "which-boxed-primitive": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/unified": {
+ "version": "11.0.4",
+ "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz",
+ "integrity": "sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "bail": "^2.0.0",
+ "devlop": "^1.0.0",
+ "extend": "^3.0.0",
+ "is-plain-obj": "^4.0.0",
+ "trough": "^2.0.0",
+ "vfile": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/unist-util-is": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz",
+ "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==",
+ "dependencies": {
+ "@types/unist": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/unist-util-position": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz",
+ "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==",
+ "dependencies": {
+ "@types/unist": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/unist-util-remove-position": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz",
+ "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "unist-util-visit": "^5.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/unist-util-stringify-position": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz",
+ "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==",
+ "dependencies": {
+ "@types/unist": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/unist-util-visit": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz",
+ "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "unist-util-is": "^6.0.0",
+ "unist-util-visit-parents": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/unist-util-visit-parents": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz",
+ "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "unist-util-is": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/update-browserslist-db": {
+ "version": "1.0.13",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
+ "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "dependencies": {
+ "escalade": "^3.1.1",
+ "picocolors": "^1.0.0"
+ },
+ "bin": {
+ "update-browserslist-db": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
+ }
+ },
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dev": true,
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/use-disposable": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/use-disposable/-/use-disposable-1.0.2.tgz",
+ "integrity": "sha512-UMaXVlV77dWOu4GqAFNjRzHzowYKUKbJBQfCexvahrYeIz4OkUYUjna4Tjjdf92NH8Nm8J7wEfFRgTIwYjO5jg==",
+ "peerDependencies": {
+ "@types/react": ">=16.8.0 <19.0.0",
+ "@types/react-dom": ">=16.8.0 <19.0.0",
+ "react": ">=16.8.0 <19.0.0",
+ "react-dom": ">=16.8.0 <19.0.0"
+ }
+ },
+ "node_modules/vfile": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz",
+ "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "unist-util-stringify-position": "^4.0.0",
+ "vfile-message": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/vfile-message": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz",
+ "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "unist-util-stringify-position": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/vite": {
+ "version": "4.4.11",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.11.tgz",
+ "integrity": "sha512-ksNZJlkcU9b0lBwAGZGGaZHCMqHsc8OpgtoYhsQ4/I2v5cnpmmmqe5pM4nv/4Hn6G/2GhTdj0DhZh2e+Er1q5A==",
+ "dev": true,
+ "dependencies": {
+ "esbuild": "^0.18.10",
+ "postcss": "^8.4.27",
+ "rollup": "^3.27.1"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ },
+ "peerDependencies": {
+ "@types/node": ">= 14",
+ "less": "*",
+ "lightningcss": "^1.21.0",
+ "sass": "*",
+ "stylus": "*",
+ "sugarss": "*",
+ "terser": "^5.4.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/which-boxed-primitive": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz",
+ "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==",
+ "dev": true,
+ "dependencies": {
+ "is-bigint": "^1.0.1",
+ "is-boolean-object": "^1.1.0",
+ "is-number-object": "^1.0.4",
+ "is-string": "^1.0.5",
+ "is-symbol": "^1.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-builtin-type": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz",
+ "integrity": "sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==",
+ "dev": true,
+ "dependencies": {
+ "function.prototype.name": "^1.1.5",
+ "has-tostringtag": "^1.0.0",
+ "is-async-function": "^2.0.0",
+ "is-date-object": "^1.0.5",
+ "is-finalizationregistry": "^1.0.2",
+ "is-generator-function": "^1.0.10",
+ "is-regex": "^1.1.4",
+ "is-weakref": "^1.0.2",
+ "isarray": "^2.0.5",
+ "which-boxed-primitive": "^1.0.2",
+ "which-collection": "^1.0.1",
+ "which-typed-array": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-collection": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz",
+ "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==",
+ "dev": true,
+ "dependencies": {
+ "is-map": "^2.0.1",
+ "is-set": "^2.0.1",
+ "is-weakmap": "^2.0.1",
+ "is-weakset": "^2.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-typed-array": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz",
+ "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==",
+ "dev": true,
+ "dependencies": {
+ "available-typed-arrays": "^1.0.5",
+ "call-bind": "^1.0.2",
+ "for-each": "^0.3.3",
+ "gopd": "^1.0.1",
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "dev": true
+ },
+ "node_modules/yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/zwitch": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz",
+ "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ }
+ }
+}
diff --git a/client/package.json b/client/package.json
new file mode 100644
index 0000000..a6ef7a9
--- /dev/null
+++ b/client/package.json
@@ -0,0 +1,38 @@
+{
+ "name": "client",
+ "private": true,
+ "version": "0.0.0",
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "vite build",
+ "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
+ "preview": "vite preview"
+ },
+ "dependencies": {
+ "@fluentui/react": "^8.115.5",
+ "@fluentui/react-components": "^9.38.0",
+ "dayjs": "^1.11.10",
+ "localforage": "^1.10.0",
+ "localstorage-slim": "^2.7.0",
+ "match-sorter": "^6.3.1",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0",
+ "react-markdown": "^9.0.1",
+ "react-router-dom": "^6.16.0",
+ "sort-by": "^1.2.0"
+ },
+ "devDependencies": {
+ "@types/react": "^18.2.15",
+ "@types/react-dom": "^18.2.7",
+ "@typescript-eslint/eslint-plugin": "^6.10.0",
+ "@typescript-eslint/parser": "^6.10.0",
+ "@vitejs/plugin-react": "^4.0.3",
+ "eslint": "^8.45.0",
+ "eslint-plugin-react": "^7.32.2",
+ "eslint-plugin-react-hooks": "^4.6.0",
+ "eslint-plugin-react-refresh": "^0.4.3",
+ "typescript": "^5.2.2",
+ "vite": "^4.4.5"
+ }
+}
diff --git a/client/src/Main.tsx b/client/src/Main.tsx
new file mode 100644
index 0000000..a314e35
--- /dev/null
+++ b/client/src/Main.tsx
@@ -0,0 +1,43 @@
+import * as React from "react";
+import * as ReactDOM from "react-dom/client";
+import { createBrowserRouter, RouterProvider } from "react-router-dom";
+import { FluentProvider, webLightTheme } from "@fluentui/react-components";
+
+import Root from "./pages/Root";
+import SessionSearch, { loader as sessionsListLoader } from "./pages/Search";
+import { Chat, action as chatAction } from "./pages/Chat";
+import { About, loader as aboutLoader } from "./pages/About";
+
+const router = createBrowserRouter([
+ {
+ path: "/",
+ element: ,
+ children: [
+ {
+ index: true,
+ element: ,
+ action: chatAction,
+ },
+ {
+ index: false,
+ element: ,
+ path: "/search",
+ loader: sessionsListLoader,
+ },
+ {
+ index: false,
+ element: ,
+ path: "/about",
+ loader: aboutLoader,
+ },
+ ],
+ },
+]);
+
+ReactDOM.createRoot(document.getElementById("root")!).render(
+
+
+
+
+
+);
diff --git a/client/src/api/chat.ts b/client/src/api/chat.ts
new file mode 100644
index 0000000..540bb75
--- /dev/null
+++ b/client/src/api/chat.ts
@@ -0,0 +1,57 @@
+import { AskResponse } from "../models";
+
+type ChatTurn = {
+ userPrompt: string;
+ responseMessage?: string;
+};
+
+type UserQuestion = {
+ question: string;
+ askedOn: Date;
+};
+
+function sleep(ms: number) {
+ return new Promise((resolve) => setTimeout(resolve, ms));
+}
+
+let questionAndAnswers: Record = {};
+
+export const ask = async (prompt: string) => {
+ const history: ChatTurn[] = [];
+ const currentMessageId = Date.now();
+ const currentQuestion = {
+ question: prompt,
+ askedOn: new Date(),
+ };
+ questionAndAnswers[currentMessageId] = [currentQuestion, undefined];
+
+ for (let id in questionAndAnswers) {
+ const [question, answer] = questionAndAnswers[id];
+ history.push({
+ userPrompt: question.question,
+ responseMessage: answer?.answer,
+ });
+ }
+
+ const response = await fetch("/api/ask", {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify(history),
+ });
+
+ const askResponse: AskResponse = await response.json();
+
+ questionAndAnswers[currentMessageId] = [
+ currentQuestion,
+ {
+ answer: askResponse.answer,
+ thoughts: askResponse.thoughts,
+ dataPoints: askResponse.dataPoints,
+ citationBaseUrl: askResponse.citationBaseUrl,
+ },
+ ];
+
+ return await Promise.resolve(questionAndAnswers);
+};
diff --git a/client/src/api/sessions.ts b/client/src/api/sessions.ts
new file mode 100644
index 0000000..49791ab
--- /dev/null
+++ b/client/src/api/sessions.ts
@@ -0,0 +1,72 @@
+export type ErrorInfo = {
+ errorSource?: string;
+ errorCode?: number;
+ errorMessage: string;
+};
+
+export type SessionInfo = {
+ id: string;
+ external_id: string;
+ title: string;
+ abstract: string;
+ start_time_PST: string;
+ end_time_PST: string;
+ cosine_similarity: number;
+ speakers: string;
+};
+
+export type SessionsResponse = {
+ sessions: SessionInfo[];
+ errorInfo?: ErrorInfo;
+};
+
+export async function getSessions(content: string): Promise {
+ const settings = {
+ method: "post",
+ headers: {
+ Accept: "application/json",
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({
+ text: content,
+ }),
+ };
+
+ const response = await fetch("/data-api/rest/find", settings);
+ if (!response.ok) {
+ return {
+ sessions: [],
+ errorInfo: {
+ errorSource: "Server",
+ errorCode: response.status,
+ errorMessage: response.statusText,
+ },
+ };
+ }
+
+ var sessions = [];
+ var errorInfo = undefined;
+ const data = await response.json();
+
+ if (data.value.length > 0) {
+ if (data.value[0].error_code) {
+ errorInfo = {
+ errorSource: data.value[0].error_source as string,
+ errorCode: data.value[0].error_code as number,
+ errorMessage: data.value[0].error_message as string,
+ };
+ } else {
+ sessions = data.value;
+ }
+ }
+
+ return { sessions: sessions, errorInfo: errorInfo };
+}
+
+export async function getSessionsCount(): Promise {
+ const response = await fetch("/data-api/rest/sessions-count");
+ if (!response.ok) return "n/a";
+ const data = await response.json();
+ const totalCount = data ? data.value[0].total_sessions : "n/a";
+ return totalCount;
+}
diff --git a/client/src/components/FancyText.tsx b/client/src/components/FancyText.tsx
new file mode 100644
index 0000000..25bab70
--- /dev/null
+++ b/client/src/components/FancyText.tsx
@@ -0,0 +1,36 @@
+import { makeStyles, Text, TextProps } from "@fluentui/react-components";
+
+const useStyles = makeStyles({
+ fancy: {
+ fontSize: "1.125rem",
+ fontFamily: "var(--base-font-family)",
+ fontWeight: 600,
+ fontStyle: "normal",
+ lineHeight: "1.688rem",
+ marginTop: "-0.1rem",
+ textDecorationColor: "none",
+ textDecorationLine: "none",
+ textTransform: "none",
+ color: "var(--color-title-font)",
+ },
+});
+
+export const FancyText = ({
+ children,
+ className,
+ block,
+ as,
+ ...rest
+}: TextProps) => {
+ const classes = useStyles();
+ return (
+
+ {children}
+
+ );
+};
diff --git a/client/src/components/Header.tsx b/client/src/components/Header.tsx
new file mode 100644
index 0000000..b59952d
--- /dev/null
+++ b/client/src/components/Header.tsx
@@ -0,0 +1,10 @@
+import { Title1 } from "@fluentui/react-components";
+import siteConfig from "../site";
+
+export const Header = () => {
+ return (
+
+ 🤖 {siteConfig.name} - Conference AI Assistant
+
+ );
+};
diff --git a/client/src/components/Navigation.tsx b/client/src/components/Navigation.tsx
new file mode 100644
index 0000000..e1f0785
--- /dev/null
+++ b/client/src/components/Navigation.tsx
@@ -0,0 +1,33 @@
+import { Divider, Tab, TabList } from "@fluentui/react-components";
+import { SearchRegular, ChatRegular, InfoRegular } from "@fluentui/react-icons";
+import { useNavigate } from "react-router-dom";
+
+export const Navigation = () => {
+ const navigate = useNavigate();
+
+ return (
+ <>
+ {
+ navigate(data.value === "chat" ? "/" : `/${data.value}`);
+ }}
+ selectedValue={
+ window.location.pathname === "/" ? "chat" : window.location.pathname.substring(1)
+ }
+ >
+ }>
+ Ask
+
+ }>
+ Search
+
+ }>
+ About
+
+
+
+
+
+ >
+ );
+};
diff --git a/client/src/components/NoSessions.tsx b/client/src/components/NoSessions.tsx
new file mode 100644
index 0000000..5b06ea0
--- /dev/null
+++ b/client/src/components/NoSessions.tsx
@@ -0,0 +1,9 @@
+export function NoSessions() {
+ return (
+
+
+ No session found
+
+
+ );
+}
diff --git a/client/src/components/PrimaryButton.tsx b/client/src/components/PrimaryButton.tsx
new file mode 100644
index 0000000..d9391f0
--- /dev/null
+++ b/client/src/components/PrimaryButton.tsx
@@ -0,0 +1,21 @@
+import { Button, ButtonProps, makeStyles } from "@fluentui/react-components";
+
+const useStyles = makeStyles({
+ button: {
+ boxShadow: "0 0 1px #0009, 0 1px 2px #0003",
+ },
+});
+
+export const PrimaryButton = ({ children, ...rest }: ButtonProps) => {
+ const classes = useStyles();
+ return (
+
+ {children}
+
+ );
+};
diff --git a/client/src/components/Session.tsx b/client/src/components/Session.tsx
new file mode 100644
index 0000000..cbdf7d0
--- /dev/null
+++ b/client/src/components/Session.tsx
@@ -0,0 +1,45 @@
+import { SessionInfo } from "../api/sessions";
+import { Text, Title2 } from "@fluentui/react-components";
+import { FancyText } from "./FancyText";
+import dayjs from "dayjs";
+import siteConfig from "../site";
+
+function formatSubtitle(session: SessionInfo) {
+ const speakers = JSON.parse(session.speakers).join(", ");
+
+ const startTime = dayjs(session.start_time_PST);
+ const endTime = dayjs(session.end_time_PST);
+
+ const day = startTime.format("dddd")
+ const start = startTime.format("hh:mm A");
+ const end = endTime.format("hh:mm A");
+
+ return `${speakers} | ${day}, ${start}-${end} | Similarity: ${session.cosine_similarity.toFixed(6)}`;
+}
+
+function formatSessionLink(session: SessionInfo) {
+ const startTime = dayjs(session.start_time_PST);
+
+ const day = startTime.format("D")
+ const url = new URL(`session-list.aspx?EventDay=${day}`, siteConfig.sessionUrl);
+
+ return url;
+}
+
+export const Session = ({ session }: { session: SessionInfo }) => {
+ return (
+
+ );
+};
diff --git a/client/src/components/SessionsList.tsx b/client/src/components/SessionsList.tsx
new file mode 100644
index 0000000..fa05cc1
--- /dev/null
+++ b/client/src/components/SessionsList.tsx
@@ -0,0 +1,12 @@
+import { SessionInfo } from "../api/sessions";
+import { Session } from "./Session";
+
+export const SessionList = ({ sessions }: { sessions: SessionInfo[] }) => {
+ return (
+
+ {sessions.map((session) => (
+
+ ))}
+
+ );
+};
diff --git a/client/src/models.ts b/client/src/models.ts
new file mode 100644
index 0000000..aaeabb8
--- /dev/null
+++ b/client/src/models.ts
@@ -0,0 +1,14 @@
+export type SupportingContentRecord = {
+ title: string;
+ content: string;
+ url: string;
+ similarity: number;
+};
+
+export type AskResponse = {
+ answer: string;
+ thoughts?: string;
+ dataPoints: SupportingContentRecord[];
+ citationBaseUrl: string;
+ error?: string | null;
+};
diff --git a/client/src/pages/About.tsx b/client/src/pages/About.tsx
new file mode 100644
index 0000000..2214408
--- /dev/null
+++ b/client/src/pages/About.tsx
@@ -0,0 +1,56 @@
+import { Suspense } from "react";
+import { Await, LoaderFunction, defer, useLoaderData } from "react-router-dom";
+import ls from "localstorage-slim";
+import { getSessionsCount } from "../api/sessions";
+import { FancyText } from "../components/FancyText";
+import siteConfig from "../site";
+
+function showSessionCount(
+ sessionsCount: string | undefined | null = undefined
+) {
+ var sc = sessionsCount;
+ if (sc === undefined) {
+ sc = ls.get("sessionsCount");
+ console.log("sessionsCount", sc);
+ } else {
+ ls.set("sessionsCount", sc, { ttl: 60 * 60 * 24 * 7 });
+ }
+ if (sc == null) {
+ return Loading session count... ;
+ }
+ return (
+
+ There are {sc} sessions indexed so far.
+
+ );
+}
+
+export const loader: LoaderFunction = async () => {
+ const sessionsCount = getSessionsCount();
+ return defer({ sessionsCount });
+};
+
+export const About = () => {
+ const { sessionsCount } = useLoaderData() as {
+ sessionsCount: string | number;
+ };
+
+ return (
+ <>
+
+ Source code and and related articles are available on GitHub. {" "}
+ The AI model used generate embeddings is the text-embedding-ada-002 and the AI model used to process and generate natural language content is gpt-4 turbo .
+
+
+ Unable to load session count 😥...
+ }
+ >
+ {(sessionsCount) => showSessionCount(sessionsCount)}
+
+
+ >
+ );
+};
diff --git a/client/src/pages/Chat.tsx b/client/src/pages/Chat.tsx
new file mode 100644
index 0000000..5782ccc
--- /dev/null
+++ b/client/src/pages/Chat.tsx
@@ -0,0 +1,137 @@
+import {
+ Body1,
+ Card,
+ CardHeader,
+ Textarea,
+ TextareaProps,
+ Text,
+ makeStyles,
+ CardFooter,
+ Spinner,
+ Title2
+} from "@fluentui/react-components";
+import { SendRegular } from "@fluentui/react-icons";
+import { useState } from "react";
+import { ActionFunctionArgs, useFetcher } from "react-router-dom";
+import { ask } from "../api/chat";
+import { FancyText } from "../components/FancyText";
+import { PrimaryButton } from "../components/PrimaryButton";
+import ReactMarkdown from "react-markdown";
+
+const useClasses = makeStyles({
+ container: {},
+ chatArea: {},
+ card: {},
+ rm: { marginBottom: "-1em", marginTop: "-1em"},
+ answersArea: { marginTop: "1em"},
+ textarea: { width: "100%", marginBottom: "1rem" },
+});
+
+export async function action({ request }: ActionFunctionArgs) {
+ let formData = await request.formData();
+ const prompt = formData.get("prompt");
+ if (!prompt) {
+ return null;
+ }
+
+ const data = await ask(prompt.toString());
+ return data;
+}
+
+const Answers = ({ data }: { data: Awaited> }) => {
+ if (!data) {
+ return null;
+ }
+ const components = [];
+ const classes = useClasses();
+
+ var cid:number = 0
+ for (const id in data) { cid = Number(id) }
+ const [question, answer] = data[cid];
+
+ components.push(
+
+ Your question
+
+ {question.question}
+
+ My answer
+
+ {answer?.answer}
+
+ My thoughts
+
+ {answer?.thoughts}
+
+
+ );
+
+ return <>{components}>;
+};
+
+export const Chat = () => {
+ const fetcher = useFetcher>>();
+ const classes = useClasses();
+
+ const submitting = fetcher.state !== "idle";
+ const data = fetcher.data;
+
+ const [prompt, setPrompt] = useState("");
+
+ const onChange: TextareaProps["onChange"] = (_, data) =>
+ setPrompt(() => data.value);
+
+ const onKeyDown: TextareaProps["onKeyDown"] = (e) => {
+ if (!prompt) {
+ return;
+ }
+
+ if (e.key === "Enter" && !e.shiftKey) {
+ const formData = new FormData();
+ formData.append("prompt", prompt);
+ fetcher.submit(formData, { method: "POST" });
+ }
+ };
+
+ return (
+
+
+
+ <>
+ Ask questions to the AI model in natural language and get meaningful answers
+ to help you navigate the conferences sessions and find the best ones for you.
+ Thanks to Prompt Engineering and Retrieval Augmented Generation (RAG) finding
+ details and recommendations on what session to attend is easier than ever. Please note that the AI model will remember your questions and answers to improve the quality of the answers and get more context on your requests.
+ If you want to start from scratch, click here or refresh the page.
+ >
+
+
+
+
+
+ }
+ disabled={submitting || !prompt}
+ >
+ Ask
+
+ {submitting && }
+
+
+
+ {!submitting && data &&
}
+
+
+ );
+};
diff --git a/client/src/pages/Root.tsx b/client/src/pages/Root.tsx
new file mode 100644
index 0000000..2a0c472
--- /dev/null
+++ b/client/src/pages/Root.tsx
@@ -0,0 +1,35 @@
+import { Outlet } from "react-router-dom";
+import { makeStyles, shorthands } from "@fluentui/react-components";
+import { Header } from "../components/Header";
+import { Navigation } from "../components/Navigation";
+
+const margin = shorthands.margin("1rem", "3rem", "1rem");
+const useStyles = makeStyles({
+ root: {
+ display: "grid",
+ gridTemplateRows: "auto 1fr",
+ gridTemplateAreas: `
+ "header"
+ "main"
+ `,
+ height: `calc(100vh - ${margin.marginTop} - ${margin.marginBottom})`,
+ ...margin,
+ },
+});
+
+export default function Root() {
+ const classes = useStyles();
+ return (
+ <>
+
+ >
+ );
+}
diff --git a/client/src/pages/Search.tsx b/client/src/pages/Search.tsx
new file mode 100644
index 0000000..6e7aefb
--- /dev/null
+++ b/client/src/pages/Search.tsx
@@ -0,0 +1,102 @@
+import { Input, Spinner } from "@fluentui/react-components";
+import { Search24Regular } from "@fluentui/react-icons";
+import {
+ Form,
+ LoaderFunction,
+ useLoaderData,
+ useNavigation,
+} from "react-router-dom";
+import { NoSessions } from "../components/NoSessions";
+import { SessionList } from "../components/SessionsList";
+import type { ErrorInfo, SessionInfo } from "../api/sessions";
+import { getSessions } from "../api/sessions";
+import { FancyText } from "../components/FancyText";
+import { PrimaryButton } from "../components/PrimaryButton";
+
+type LoaderData = {
+ sessions: SessionInfo[];
+ searchQuery: string;
+ isSearch: boolean;
+ errorInfo: ErrorInfo | null;
+};
+
+const SEARCH_INPUT_ID = "q";
+
+export const loader: LoaderFunction = async ({ request }) => {
+ const url = new URL(request.url);
+ const searchQuery = url.searchParams.get(SEARCH_INPUT_ID) ?? "";
+ const isSearch = searchQuery !== "";
+
+ if (!isSearch) {
+ return { sessions: [] };
+ }
+
+ let { sessions, errorInfo } = await getSessions(searchQuery);
+ if (!Array.isArray(sessions)) {
+ errorInfo = { errorMessage: "Error: sessions is not an array" };
+ sessions = [];
+ }
+ return { sessions, searchQuery, isSearch, errorInfo };
+};
+
+export default function SessionSearch() {
+ const { sessions, searchQuery, isSearch, errorInfo } = useLoaderData() as LoaderData;
+ const navigation = useNavigation();
+
+ const searching =
+ navigation.location &&
+ new URLSearchParams(navigation.location.search).has(SEARCH_INPUT_ID);
+
+ return (
+ <>
+
+ <>
+ Use OpenAI to search for interesting sessions. Write the topic you're
+ interested in, and (up to) the top ten most interesting and related
+ session will be returned. The search is done using text embeddings and
+ then using cosine similarity to find the most similar sessions.
+ >
+
+
+
+ {!errorInfo ? (
+ ""
+ ) : (
+
+ {"Error" + errorInfo.errorMessage}
+
+ )}
+ {sessions.length > 0 &&
}
+ {sessions.length === 0 && isSearch &&
}
+
+ >
+ );
+}
+
diff --git a/client/src/site.ts b/client/src/site.ts
new file mode 100644
index 0000000..d521ed9
--- /dev/null
+++ b/client/src/site.ts
@@ -0,0 +1,7 @@
+const siteConfig = {
+ name: 'VSLive! Las Vegas 2024',
+ website: 'https://vslive.com/events/las-vegas-2024',
+ sessionUrl: 'https://vslive.com/Events/Las-Vegas-2024/Sessions/',
+}
+
+export default siteConfig;
\ No newline at end of file
diff --git a/client/src/user.ts b/client/src/user.ts
new file mode 100644
index 0000000..d153ebf
--- /dev/null
+++ b/client/src/user.ts
@@ -0,0 +1,8 @@
+export async function getUserInfo()
+{
+ const response = await fetch('/.auth/me');
+ const payload = await response.json();
+ const { clientPrincipal } = payload;
+ return clientPrincipal;
+}
+
diff --git a/client/staticwebapp.config.json b/client/staticwebapp.config.json
new file mode 100644
index 0000000..1e812ac
--- /dev/null
+++ b/client/staticwebapp.config.json
@@ -0,0 +1,5 @@
+{
+ "navigationFallback": {
+ "rewrite": "/"
+ }
+}
\ No newline at end of file
diff --git a/client/tsconfig.json b/client/tsconfig.json
new file mode 100644
index 0000000..a7fc6fb
--- /dev/null
+++ b/client/tsconfig.json
@@ -0,0 +1,25 @@
+{
+ "compilerOptions": {
+ "target": "ES2020",
+ "useDefineForClassFields": true,
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
+ "module": "ESNext",
+ "skipLibCheck": true,
+
+ /* Bundler mode */
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true,
+ "jsx": "react-jsx",
+
+ /* Linting */
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noFallthroughCasesInSwitch": true
+ },
+ "include": ["src"],
+ "references": [{ "path": "./tsconfig.node.json" }]
+}
diff --git a/client/tsconfig.node.json b/client/tsconfig.node.json
new file mode 100644
index 0000000..42872c5
--- /dev/null
+++ b/client/tsconfig.node.json
@@ -0,0 +1,10 @@
+{
+ "compilerOptions": {
+ "composite": true,
+ "skipLibCheck": true,
+ "module": "ESNext",
+ "moduleResolution": "bundler",
+ "allowSyntheticDefaultImports": true
+ },
+ "include": ["vite.config.ts"]
+}
diff --git a/client/vite.config.ts b/client/vite.config.ts
new file mode 100644
index 0000000..5a33944
--- /dev/null
+++ b/client/vite.config.ts
@@ -0,0 +1,7 @@
+import { defineConfig } from 'vite'
+import react from '@vitejs/plugin-react'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [react()],
+})
diff --git a/database/SessionRecommender/Script.PostDeployment.sql b/database/SessionRecommender/Script.PostDeployment.sql
new file mode 100644
index 0000000..2157524
--- /dev/null
+++ b/database/SessionRecommender/Script.PostDeployment.sql
@@ -0,0 +1,7 @@
+-- This file contains SQL statements that will be executed after the build script.
+
+alter table [web].[sessions] enable change_tracking with (track_columns_updated = off);
+go
+
+alter table [web].[speakers] enable change_tracking with (track_columns_updated = off);
+go
diff --git a/database/SessionRecommender/Script.PreDeployment.sql b/database/SessionRecommender/Script.PreDeployment.sql
new file mode 100644
index 0000000..ac90e05
--- /dev/null
+++ b/database/SessionRecommender/Script.PreDeployment.sql
@@ -0,0 +1,15 @@
+if not exists(select * from sys.symmetric_keys where [name] = '##MS_DatabaseMasterKey##')
+begin
+ create master key encryption by password = N'V3RYStr0NGP@ssw0rd!';
+end
+go
+
+if exists(select * from sys.[database_scoped_credentials] where name = '$(OPEN_AI_ENDPOINT)')
+begin
+ drop database scoped credential [$(OPEN_AI_ENDPOINT)];
+end
+go
+
+create database scoped credential [$(OPEN_AI_ENDPOINT)]
+with identity = 'HTTPEndpointHeaders', secret = '{"api-key":"$(OPEN_AI_KEY)"}';
+go
diff --git a/database/SessionRecommender/Security/db_owner.sql b/database/SessionRecommender/Security/db_owner.sql
new file mode 100644
index 0000000..4113d8c
--- /dev/null
+++ b/database/SessionRecommender/Security/db_owner.sql
@@ -0,0 +1 @@
+alter role [db_owner] add member [session_recommender_app];
\ No newline at end of file
diff --git a/database/SessionRecommender/Security/session_recommender_app.sql b/database/SessionRecommender/Security/session_recommender_app.sql
new file mode 100644
index 0000000..beef9d7
--- /dev/null
+++ b/database/SessionRecommender/Security/session_recommender_app.sql
@@ -0,0 +1,2 @@
+create user [session_recommender_app] with password = '$(APP_USER_PASSWORD)';
+go
diff --git a/database/SessionRecommender/Security/web.sql b/database/SessionRecommender/Security/web.sql
new file mode 100644
index 0000000..c9ff839
--- /dev/null
+++ b/database/SessionRecommender/Security/web.sql
@@ -0,0 +1,4 @@
+CREATE SCHEMA [web]
+ AUTHORIZATION [dbo];
+GO
+
diff --git a/database/SessionRecommender/Sequences/global_id.sql b/database/SessionRecommender/Sequences/global_id.sql
new file mode 100644
index 0000000..85ee211
--- /dev/null
+++ b/database/SessionRecommender/Sequences/global_id.sql
@@ -0,0 +1,6 @@
+CREATE SEQUENCE [web].[global_id]
+ AS INT
+ START WITH 1
+ INCREMENT BY 1;
+GO
+
diff --git a/database/SessionRecommender/StoredProcedures/find_sessions.sql b/database/SessionRecommender/StoredProcedures/find_sessions.sql
new file mode 100644
index 0000000..b43cbb9
--- /dev/null
+++ b/database/SessionRecommender/StoredProcedures/find_sessions.sql
@@ -0,0 +1,146 @@
+create procedure [web].[find_sessions]
+@text nvarchar(max),
+@top int = 10,
+@min_similarity decimal(19,16) = 0.75
+as
+if (@text is null) return;
+
+declare @sid as int = -1;
+if (@text like N'***%') begin
+ set @text = trim(cast(substring(@text, 4, len(@text) - 3) as nvarchar(max)));
+end else begin
+ insert into web.searched_text (searched_text) values (@text);
+ set @sid = scope_identity();
+end;
+
+declare @startTime as datetime2(7) = sysdatetime()
+
+declare @retval int, @response nvarchar(max);
+declare @payload nvarchar(max);
+set @payload = json_object('input': @text);
+
+begin try
+ exec @retval = sp_invoke_external_rest_endpoint
+ @url = '$(OPEN_AI_ENDPOINT)/openai/deployments/$(OPEN_AI_DEPLOYMENT)/embeddings?api-version=2023-03-15-preview',
+ @method = 'POST',
+ @credential = [$(OPEN_AI_ENDPOINT)],
+ @payload = @payload,
+ @response = @response output;
+end try
+begin catch
+ select
+ 'SQL' as error_source,
+ error_number() as error_code,
+ error_message() as error_message
+ return;
+end catch
+
+if (@retval != 0) begin
+ select
+ 'OPENAI' as error_source,
+ json_value(@response, '$.result.error.code') as error_code,
+ json_value(@response, '$.result.error.message') as error_message,
+ @response as error_response
+ return;
+end;
+
+declare @endTime1 as datetime2(7) = sysdatetime();
+update [web].[searched_text] set ms_rest_call = datediff(ms, @startTime, @endTime1) where id = @sid;
+
+with cteVector as
+(
+ select
+ cast([key] as int) as [vector_value_id],
+ cast([value] as float) as [vector_value]
+ from
+ openjson(json_query(@response, '$.result.data[0].embedding'))
+),
+cteSimilarSpeakers as
+(
+ select
+ v2.id as speaker_id,
+ -- Optimized as per https://platform.openai.com/docs/guides/embeddings/which-distance-function-should-i-use
+ sum(v1.[vector_value] * v2.[vector_value]) as cosine_similarity
+ from
+ cteVector v1
+ inner join
+ web.speakers_embeddings v2 on v1.vector_value_id = v2.vector_value_id
+ group by
+ v2.id
+
+),
+cteSimilar as
+(
+ select
+ v2.id as session_id,
+ -- Optimized as per https://platform.openai.com/docs/guides/embeddings/which-distance-function-should-i-use
+ sum(v1.[vector_value] * v2.[vector_value]) as cosine_similarity
+ from
+ cteVector v1
+ inner join
+ web.sessions_embeddings v2 on v1.vector_value_id = v2.vector_value_id
+ group by
+ v2.id
+
+ union all
+
+ select
+ ss.session_id,
+ s.cosine_similarity
+ from
+ web.sessions_speakers ss
+ inner join
+ cteSimilarSpeakers s on s.speaker_id = ss.speaker_id
+),
+cteSimilar2 as (
+ select
+ *,
+ rn = row_number() over (partition by session_id order by cosine_similarity desc)
+ from
+ cteSimilar
+),
+cteSpeakers as
+(
+ select
+ session_id,
+ json_query('["' + string_agg(string_escape(full_name, 'json'), '","') + '"]') as speakers
+ from
+ web.sessions_speakers ss
+ inner join
+ web.speakers sp on sp.id = ss.speaker_id
+ group by
+ session_id
+)
+select top(@top)
+ a.id,
+ a.title,
+ a.abstract,
+ a.external_id,
+ a.start_time_PST,
+ a.end_time_PST,
+ a.recording_url,
+ isnull((select top (1) speakers from cteSpeakers where session_id = a.id), '[]') as speakers,
+ r.cosine_similarity
+from
+ cteSimilar2 r
+inner join
+ web.sessions a on r.session_id = a.id
+where
+ r.cosine_similarity > @min_similarity
+and
+ rn = 1
+order by
+ r.cosine_similarity desc, a.title asc;
+
+declare @rc int = @@rowcount;
+
+declare @endTime2 as datetime2(7) = sysdatetime()
+update
+ [web].[searched_text]
+set
+ ms_vector_search = datediff(ms, @endTime1, @endTime2),
+ found_sessions = @rc
+where
+ id = @sid
+GO
+
diff --git a/database/SessionRecommender/StoredProcedures/get_sessions_count.sql b/database/SessionRecommender/StoredProcedures/get_sessions_count.sql
new file mode 100644
index 0000000..1590d12
--- /dev/null
+++ b/database/SessionRecommender/StoredProcedures/get_sessions_count.sql
@@ -0,0 +1,5 @@
+create procedure [web].[get_sessions_count]
+as
+select count(*) as total_sessions from [web].[sessions];
+GO
+
diff --git a/database/SessionRecommender/StoredProcedures/upsert_session_embeddings.sql b/database/SessionRecommender/StoredProcedures/upsert_session_embeddings.sql
new file mode 100644
index 0000000..8d83de5
--- /dev/null
+++ b/database/SessionRecommender/StoredProcedures/upsert_session_embeddings.sql
@@ -0,0 +1,23 @@
+
+create procedure [web].[upsert_session_embeddings]
+@id int,
+@embeddings nvarchar(max)
+as
+
+set xact_abort on
+set transaction isolation level serializable
+
+begin transaction
+
+ delete from web.sessions_embeddings
+ where id = @id
+
+ insert into web.sessions_embeddings
+ select @id, cast([key] as int), cast([value] as float)
+ from openjson(@embeddings)
+
+ update web.sessions set require_embeddings_update = 0 where id = @id
+
+commit
+GO
+
diff --git a/database/SessionRecommender/StoredProcedures/upsert_speaker_embeddings.sql b/database/SessionRecommender/StoredProcedures/upsert_speaker_embeddings.sql
new file mode 100644
index 0000000..a641df5
--- /dev/null
+++ b/database/SessionRecommender/StoredProcedures/upsert_speaker_embeddings.sql
@@ -0,0 +1,23 @@
+
+create procedure [web].[upsert_speaker_embeddings]
+@id int,
+@embeddings nvarchar(max)
+as
+
+set xact_abort on
+set transaction isolation level serializable
+
+begin transaction
+
+ delete from web.speakers_embeddings
+ where id = @id
+
+ insert into web.speakers_embeddings
+ select @id, cast([key] as int), cast([value] as float)
+ from openjson(@embeddings)
+
+ update web.speakers set require_embeddings_update = 0 where id = @id
+
+commit
+GO
+
diff --git a/database/SessionRecommender/Tables/searched_text.sql b/database/SessionRecommender/Tables/searched_text.sql
new file mode 100644
index 0000000..980ca8d
--- /dev/null
+++ b/database/SessionRecommender/Tables/searched_text.sql
@@ -0,0 +1,11 @@
+CREATE TABLE [web].[searched_text] (
+ [id] INT IDENTITY (1, 1) NOT NULL,
+ [searched_text] NVARCHAR (MAX) NOT NULL,
+ [search_datetime] DATETIME2 (7) DEFAULT (sysdatetime()) NOT NULL,
+ [ms_rest_call] INT NULL,
+ [ms_vector_search] INT NULL,
+ [found_sessions] INT NULL,
+ PRIMARY KEY CLUSTERED ([id] ASC)
+);
+GO
+
diff --git a/database/SessionRecommender/Tables/sessions.sql b/database/SessionRecommender/Tables/sessions.sql
new file mode 100644
index 0000000..991adac
--- /dev/null
+++ b/database/SessionRecommender/Tables/sessions.sql
@@ -0,0 +1,20 @@
+CREATE TABLE [web].[sessions] (
+ [id] INT DEFAULT (NEXT VALUE FOR [web].[global_id]) NOT NULL,
+ [title] NVARCHAR (200) NOT NULL,
+ [abstract] NVARCHAR (MAX) NOT NULL,
+ [external_id] VARCHAR (100) COLLATE Latin1_General_100_BIN2 NULL,
+ [last_fetched] DATETIME2 (7) NULL,
+ [start_time_PST] DATETIME2 (0) NULL,
+ [end_time_PST] DATETIME2 (0) NULL,
+ [tags] NVARCHAR (MAX) NULL,
+ [recording_url] VARCHAR (1000) NULL,
+ [require_embeddings_update] BIT DEFAULT ((0)) NOT NULL,
+ [embeddings] NVARCHAR (MAX) NULL,
+ PRIMARY KEY CLUSTERED ([id] ASC),
+ CHECK (isjson([tags])=(1)),
+ UNIQUE NONCLUSTERED ([title] ASC)
+);
+GO
+
+
+
diff --git a/database/SessionRecommender/Tables/sessions_embeddings.sql b/database/SessionRecommender/Tables/sessions_embeddings.sql
new file mode 100644
index 0000000..4473505
--- /dev/null
+++ b/database/SessionRecommender/Tables/sessions_embeddings.sql
@@ -0,0 +1,12 @@
+CREATE TABLE [web].[sessions_embeddings] (
+ [id] INT NOT NULL,
+ [vector_value_id] INT NOT NULL,
+ [vector_value] DECIMAL (19, 16) NOT NULL,
+ CONSTRAINT fk__sessions_embeddings__sessions FOREIGN KEY ([id]) REFERENCES [web].[sessions] ([id])
+);
+GO
+
+CREATE CLUSTERED COLUMNSTORE INDEX [IXCC]
+ ON [web].[sessions_embeddings];
+GO
+
diff --git a/database/SessionRecommender/Tables/sessions_speakers.sql b/database/SessionRecommender/Tables/sessions_speakers.sql
new file mode 100644
index 0000000..2fcbb66
--- /dev/null
+++ b/database/SessionRecommender/Tables/sessions_speakers.sql
@@ -0,0 +1,14 @@
+CREATE TABLE [web].[sessions_speakers] (
+ [session_id] INT NOT NULL,
+ [speaker_id] INT NOT NULL,
+ PRIMARY KEY CLUSTERED ([session_id] ASC, [speaker_id] ASC),
+ CONSTRAINT fk__sessions_speakers__sessions FOREIGN KEY ([session_id]) REFERENCES [web].[sessions] ([id]),
+ CONSTRAINT fk__sessions_speakers__speakers FOREIGN KEY ([speaker_id]) REFERENCES [web].[speakers] ([id])
+);
+GO
+
+
+CREATE NONCLUSTERED INDEX [ix2]
+ ON [web].[sessions_speakers]([speaker_id] ASC);
+GO
+
diff --git a/database/SessionRecommender/Tables/speakers.sql b/database/SessionRecommender/Tables/speakers.sql
new file mode 100644
index 0000000..de21003
--- /dev/null
+++ b/database/SessionRecommender/Tables/speakers.sql
@@ -0,0 +1,12 @@
+CREATE TABLE [web].[speakers] (
+ [id] INT DEFAULT (NEXT VALUE FOR [web].[global_id]) NOT NULL,
+ [external_id] VARCHAR (100) COLLATE Latin1_General_100_BIN2 NULL,
+ [full_name] NVARCHAR (100) NOT NULL,
+ [require_embeddings_update] BIT DEFAULT ((0)) NOT NULL,
+ [embeddings] NVARCHAR (MAX) NULL,
+
+ PRIMARY KEY CLUSTERED ([id] ASC),
+ UNIQUE NONCLUSTERED ([full_name] ASC),
+ CHECK (isjson([embeddings])=(1))
+);
+GO
diff --git a/database/SessionRecommender/Tables/speakers_embeddings.sql b/database/SessionRecommender/Tables/speakers_embeddings.sql
new file mode 100644
index 0000000..6818ccd
--- /dev/null
+++ b/database/SessionRecommender/Tables/speakers_embeddings.sql
@@ -0,0 +1,12 @@
+CREATE TABLE [web].[speakers_embeddings] (
+ [id] INT NOT NULL,
+ [vector_value_id] INT NOT NULL,
+ [vector_value] DECIMAL (19, 16) NOT NULL,
+ CONSTRAINT fk__speakers_embeddings__speakers FOREIGN KEY ([id]) REFERENCES [web].[speakers] ([id])
+);
+GO
+
+CREATE CLUSTERED COLUMNSTORE INDEX [IXCC]
+ ON [web].[speakers_embeddings];
+GO
+
diff --git a/database/SessionRecommender/Views/last_searches.sql b/database/SessionRecommender/Views/last_searches.sql
new file mode 100644
index 0000000..f5449bc
--- /dev/null
+++ b/database/SessionRecommender/Views/last_searches.sql
@@ -0,0 +1,15 @@
+create view [web].last_searches
+as
+select top (100)
+ id,
+ searched_text,
+ switchoffset(search_datetime, '-08:00') as search_datetime_pst,
+ ms_rest_call,
+ ms_vector_search,
+ found_sessions
+from
+ [web].searched_text
+order by
+ id desc
+GO
+
diff --git a/database/SessionRecommender/Views/search_stats.sql b/database/SessionRecommender/Views/search_stats.sql
new file mode 100644
index 0000000..33e5b16
--- /dev/null
+++ b/database/SessionRecommender/Views/search_stats.sql
@@ -0,0 +1,9 @@
+create view [web].search_stats
+as
+select
+ count(*) as total_searches,
+ avg(ms_vector_search) as avg_ms_vector_search
+from
+ [web].searched_text
+GO
+
diff --git a/database/SessionRecommender/session_recommender_v2.sqlproj b/database/SessionRecommender/session_recommender_v2.sqlproj
new file mode 100644
index 0000000..598afd5
--- /dev/null
+++ b/database/SessionRecommender/session_recommender_v2.sqlproj
@@ -0,0 +1,50 @@
+
+
+
+
+ session_recommender_v2
+ {A3BB1F3B-AAAF-4735-A73F-46B26F8B66C0}
+ Microsoft.Data.Tools.Schema.Sql.SqlAzureV12DatabaseSchemaProvider
+ 1033, CI
+ True
+
+
+
+ 160.0.0
+ True
+ master
+
+
+
+
+ $(SqlCmdVar__4)
+ APP_USER_PASSWORD
+
+
+ $(SqlCmdVar__1)
+ https://dm-open-ai-3.openai.azure.com/
+
+
+ $(SqlCmdVar__2)
+ embeddings
+
+
+ $(SqlCmdVar__3)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/database/master.dacpac b/database/master.dacpac
new file mode 100644
index 0000000..bff7866
Binary files /dev/null and b/database/master.dacpac differ
diff --git a/database/session_recommender_v2.dacpac b/database/session_recommender_v2.dacpac
new file mode 100644
index 0000000..7edc6bc
Binary files /dev/null and b/database/session_recommender_v2.dacpac differ
diff --git a/database/setup-database.ps1 b/database/setup-database.ps1
new file mode 100644
index 0000000..466fa8f
--- /dev/null
+++ b/database/setup-database.ps1
@@ -0,0 +1,26 @@
+Invoke-WebRequest -Uri https://aka.ms/sqlpackage-linux -OutFile sqlpackage.zip
+
+Expand-Archive ./sqlpackage.zip sqlpackage/
+
+chmod a+x ./sqlpackage/sqlpackage
+
+./sqlpackage/sqlpackage /version
+
+Write-Host "Downloading dacpacs"
+
+Invoke-WebRequest -Uri https://github.com/azure-samples/azure-sql-db-session-recommender-v2/raw/main/database/session_recommender_v2.dacpac -OutFile session_recommender_v2.dacpac
+Invoke-WebRequest -Uri https://github.com/azure-samples/azure-sql-db-session-recommender-v2/raw/main/database/master.dacpac -OutFile master.dacpac
+
+Write-Host "Deploying database to $Env:DBSERVER with name $Env:DBNAME"
+
+./sqlpackage/sqlpackage `
+ /Action:Publish `
+ /SourceFile:"session_recommender_v2.dacpac" `
+ /TargetDatabaseName:"$Env:DBNAME" `
+ /TargetServerName:"$Env:DBSERVER" `
+ /TargetUser:"$Env:SQLADMIN" `
+ /TargetPassword:"$Env:SQLCMDPASSWORD" `
+ /v:OPEN_AI_ENDPOINT="$Env:OPEN_AI_ENDPOINT" `
+ /v:OPEN_AI_DEPLOYMENT="$Env:OPEN_AI_DEPLOYMENT" `
+ /v:OPEN_AI_KEY="$Env:OPEN_AI_KEY" `
+ /v:APP_USER_PASSWORD="$Env:APP_USER_PASSWORD"
diff --git a/func/.gitignore b/func/.gitignore
new file mode 100644
index 0000000..ff5b00c
--- /dev/null
+++ b/func/.gitignore
@@ -0,0 +1,264 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# Azure Functions localsettings file
+local.settings.json
+
+# User-specific files
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+
+# Visual Studio 2015 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUNIT
+*.VisualState.xml
+TestResult.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# DNX
+project.lock.json
+project.fragment.lock.json
+artifacts/
+
+*_i.c
+*_p.c
+*_i.h
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# JustCode is a .NET coding add-in
+.JustCode
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# TODO: Comment the next line if you want to checkin your web deploy settings
+# but database connection strings (with potential passwords) will be unencrypted
+#*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# The packages folder can be ignored because of Package Restore
+**/packages/*
+# except build/, which is used as an MSBuild target.
+!**/packages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/packages/repositories.config
+# NuGet v3's project.json files produces more ignoreable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.jfm
+*.pfx
+*.publishsettings
+node_modules/
+orleans.codegen.cs
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+
+# SQL Server files
+*.mdf
+*.ldf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# JetBrains Rider
+.idea/
+*.sln.iml
+
+# CodeRush
+.cr/
+
+# Python Tools for Visual Studio (PTVS)
+__pycache__/
+*.pyc
\ No newline at end of file
diff --git a/func/.vscode/extensions.json b/func/.vscode/extensions.json
new file mode 100644
index 0000000..bb76300
--- /dev/null
+++ b/func/.vscode/extensions.json
@@ -0,0 +1,6 @@
+{
+ "recommendations": [
+ "ms-azuretools.vscode-azurefunctions",
+ "ms-dotnettools.csharp"
+ ]
+}
\ No newline at end of file
diff --git a/func/.vscode/launch.json b/func/.vscode/launch.json
new file mode 100644
index 0000000..894cbe6
--- /dev/null
+++ b/func/.vscode/launch.json
@@ -0,0 +1,11 @@
+{
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "Attach to .NET Functions",
+ "type": "coreclr",
+ "request": "attach",
+ "processId": "${command:azureFunctions.pickProcess}"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/func/.vscode/settings.json b/func/.vscode/settings.json
new file mode 100644
index 0000000..eed4725
--- /dev/null
+++ b/func/.vscode/settings.json
@@ -0,0 +1,7 @@
+{
+ "azureFunctions.deploySubpath": "bin/Release/net8.0/publish",
+ "azureFunctions.projectLanguage": "C#",
+ "azureFunctions.projectRuntime": "~4",
+ "debug.internalConsoleOptions": "neverOpen",
+ "azureFunctions.preDeployTask": "publish (functions)"
+}
\ No newline at end of file
diff --git a/func/.vscode/tasks.json b/func/.vscode/tasks.json
new file mode 100644
index 0000000..5199259
--- /dev/null
+++ b/func/.vscode/tasks.json
@@ -0,0 +1,69 @@
+{
+ "version": "2.0.0",
+ "tasks": [
+ {
+ "label": "clean (functions)",
+ "command": "dotnet",
+ "args": [
+ "clean",
+ "/property:GenerateFullPaths=true",
+ "/consoleloggerparameters:NoSummary"
+ ],
+ "type": "process",
+ "problemMatcher": "$msCompile"
+ },
+ {
+ "label": "build (functions)",
+ "command": "dotnet",
+ "args": [
+ "build",
+ "/property:GenerateFullPaths=true",
+ "/consoleloggerparameters:NoSummary"
+ ],
+ "type": "process",
+ "dependsOn": "clean (functions)",
+ "group": {
+ "kind": "build",
+ "isDefault": true
+ },
+ "problemMatcher": "$msCompile"
+ },
+ {
+ "label": "clean release (functions)",
+ "command": "dotnet",
+ "args": [
+ "clean",
+ "--configuration",
+ "Release",
+ "/property:GenerateFullPaths=true",
+ "/consoleloggerparameters:NoSummary"
+ ],
+ "type": "process",
+ "problemMatcher": "$msCompile"
+ },
+ {
+ "label": "publish (functions)",
+ "command": "dotnet",
+ "args": [
+ "publish",
+ "--configuration",
+ "Release",
+ "/property:GenerateFullPaths=true",
+ "/consoleloggerparameters:NoSummary"
+ ],
+ "type": "process",
+ "dependsOn": "clean release (functions)",
+ "problemMatcher": "$msCompile"
+ },
+ {
+ "type": "func",
+ "dependsOn": "build (functions)",
+ "options": {
+ "cwd": "${workspaceFolder}/bin/Debug/net8.0"
+ },
+ "command": "host start",
+ "isBackground": true,
+ "problemMatcher": "$func-dotnet-watch"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/func/ChatHandler.cs b/func/ChatHandler.cs
new file mode 100644
index 0000000..6b868cb
--- /dev/null
+++ b/func/ChatHandler.cs
@@ -0,0 +1,123 @@
+using System;
+using System.Data;
+using System.Text.Json;
+using Azure;
+using Azure.AI.OpenAI;
+using Dapper;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Azure.Functions.Worker;
+using Microsoft.Data.SqlClient;
+using Microsoft.Extensions.Logging;
+using FromBodyAttribute = Microsoft.Azure.Functions.Worker.Http.FromBodyAttribute;
+
+namespace SessionRecommender.RequestHandler;
+
+public record ChatTurn(string userPrompt, string? responseMessage);
+
+public record FoundSession(
+ int Id,
+ string Title,
+ string Abstract,
+ double Similarity,
+ //string RecordingUrl,
+ string Speakers,
+ string ExternalId,
+ DateTimeOffset Start,
+ DateTimeOffset End
+);
+
+public class ChatHandler(OpenAIClient openAIClient, SqlConnection conn, ILogger logger)
+{
+ private readonly string _openAIDeploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_GPT_DEPLOYMENT_NAME") ?? "gpt-4";
+
+ private const string SystemMessage = """
+You are a system assistant who helps users find the right session to watch from the conference, based off the sessions that are provided to you.
+
+Sessions will be provided in an assistant message in the format of `title|abstract|speakers|start-time|end-time`. You can use this information to help you answer the user's question.
+""";
+
+ [Function("ChatHandler")]
+ public async Task AskAsync(
+ [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "ask")] HttpRequest req,
+ [FromBody] ChatTurn[] history)
+ {
+ logger.LogInformation("Retrieving similar sessions...");
+
+ DynamicParameters p = new();
+ p.Add("@text", history.Last().userPrompt);
+ p.Add("@top", 25);
+ p.Add("@min_similarity", 0.70);
+
+ using IDataReader foundSessions = await conn.ExecuteReaderAsync("[web].[find_sessions]", commandType: CommandType.StoredProcedure, param: p);
+
+ List sessions = [];
+ while (foundSessions.Read())
+ {
+ sessions.Add(new(
+ Id: foundSessions.GetInt32(0),
+ Title: foundSessions.GetString(1),
+ Abstract: foundSessions.GetString(2),
+ ExternalId: foundSessions.GetString(3),
+ Start: foundSessions.GetDateTime(4),
+ End: foundSessions.GetDateTime(5),
+ //RecordingUrl: foundSessions.GetString(6),
+ Speakers: foundSessions.GetString(7),
+ Similarity: foundSessions.GetDouble(8)
+ ));
+ }
+
+ logger.LogInformation("Calling GPT...");
+
+ string sessionDescriptions = string.Join("\r", sessions.Select(s => $"{s.Title}|{s.Abstract}|{s.Speakers}|{s.Start}|{s.End}"));
+
+ List messages = [new ChatRequestSystemMessage(SystemMessage)];
+
+ foreach (ChatTurn turn in history)
+ {
+ messages.Add(new ChatRequestUserMessage(turn.userPrompt));
+ if (turn.responseMessage is not null)
+ {
+ messages.Add(new ChatRequestAssistantMessage(turn.responseMessage));
+ }
+ }
+
+ messages.Add(new ChatRequestUserMessage($@"## Source ##
+{sessionDescriptions}
+## End ##
+
+You answer needs to divided in two sections: in the first section you'll add the answer to the question.
+In the second section, that must be named exactly '###thoughts###', and you must use the section name as typed, without any changes, you'll write brief thoughts on how you came up with the answer, e.g. what sources you used, what you thought about, etc.
+}}"));
+
+ ChatCompletionsOptions options = new(_openAIDeploymentName, messages);
+
+ try
+ {
+ var answerPayload = await openAIClient.GetChatCompletionsAsync(options);
+ var answerContent = answerPayload.Value.Choices[0].Message.Content;
+
+ //logger.LogInformation(answerContent);
+
+ var answerPieces = answerContent
+ .Replace("###Thoughts###", "###thoughts###", StringComparison.InvariantCultureIgnoreCase)
+ .Replace("### Thoughts ###", "###thoughts###", StringComparison.InvariantCultureIgnoreCase)
+ .Split("###thoughts###", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
+ var answer = answerPieces[0];
+ var thoughts = answerPieces.Length == 2 ? answerPieces[1] : "No thoughts provided.";
+
+ logger.LogInformation("Done.");
+
+ return new OkObjectResult(new
+ {
+ answer,
+ thoughts
+ });
+ }
+ catch (Exception e)
+ {
+ logger.LogError(e, "Failed to get answer from OpenAI.");
+ return new BadRequestObjectResult(e.Message);
+ }
+ }
+}
\ No newline at end of file
diff --git a/func/Program.cs b/func/Program.cs
new file mode 100644
index 0000000..f17786c
--- /dev/null
+++ b/func/Program.cs
@@ -0,0 +1,45 @@
+using Azure;
+using Azure.AI.OpenAI;
+using Azure.Identity;
+using Azure.Security.KeyVault.Secrets;
+using Microsoft.Data.SqlClient;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+
+var host = new HostBuilder()
+
+.ConfigureServices(services =>
+{
+ Uri openaiEndPoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT") is string value &&
+ Uri.TryCreate(value, UriKind.Absolute, out Uri? uri) &&
+ uri is not null
+ ? uri
+ : throw new ArgumentException(
+ $"Unable to parse endpoint URI");
+
+ string? apiKey;
+ var keyVaultEndpoint = Environment.GetEnvironmentVariable("AZURE_KEY_VAULT_ENDPOINT");
+ if (!string.IsNullOrEmpty(keyVaultEndpoint))
+ {
+ var openAIKeyName = Environment.GetEnvironmentVariable("AZURE_OPENAI_KEY");
+ var keyVaultClient = new SecretClient(vaultUri: new Uri(keyVaultEndpoint), credential: new DefaultAzureCredential());
+ apiKey = keyVaultClient.GetSecret(openAIKeyName).Value.Value;
+ }
+ else
+ {
+ apiKey = Environment.GetEnvironmentVariable("AZURE_OPENAI_KEY");
+ }
+
+ OpenAIClient openAIClient = apiKey != null ?
+ new(openaiEndPoint, new AzureKeyCredential(apiKey)) :
+ new(openaiEndPoint, new DefaultAzureCredential());
+
+ services.AddSingleton(openAIClient);
+
+ services.AddTransient((_) => new SqlConnection(Environment.GetEnvironmentVariable("AZURE_SQL_CONNECTION_STRING")));
+
+})
+.ConfigureFunctionsWebApplication()
+.Build();
+
+host.Run();
\ No newline at end of file
diff --git a/func/RequestHandler.csproj b/func/RequestHandler.csproj
new file mode 100644
index 0000000..2a08e4a
--- /dev/null
+++ b/func/RequestHandler.csproj
@@ -0,0 +1,29 @@
+
+
+ net8.0
+ v4
+ Exe
+ enable
+ enable
+ preview
+ f9d76b6e-3000-45fa-8f99-dec6e7819a55
+
+
+
+
+
+
+
+
+
+
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+ Never
+
+
+
diff --git a/func/SessionProcessor.cs b/func/SessionProcessor.cs
new file mode 100644
index 0000000..fe69fad
--- /dev/null
+++ b/func/SessionProcessor.cs
@@ -0,0 +1,145 @@
+using Microsoft.Extensions.Logging;
+using Microsoft.Data.SqlClient;
+using System.Data;
+using Dapper;
+using Microsoft.Azure.Functions.Worker;
+using Microsoft.Azure.Functions.Worker.Extensions.Sql;
+using Azure.AI.OpenAI;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace SessionRecommender.RequestHandler;
+
+public class Item
+{
+ public required int Id { get; set; }
+
+ [JsonPropertyName("require_embeddings_update")]
+ public bool RequireEmbeddingsUpdate { get; set; }
+
+ public override bool Equals(object obj)
+ {
+ if (obj is not Item that) return false;
+ return Id == that.Id;
+ }
+
+ public override int GetHashCode()
+ {
+ return Id.GetHashCode();
+ }
+
+ public override string ToString()
+ {
+ return Id.ToString();
+ }
+}
+
+public class Session: Item
+{
+ public string? Title { get; set; }
+
+ public string? Abstract { get; set; }
+}
+
+public class Speaker: Item
+{
+ [JsonPropertyName("full_name")]
+ public string? FullName { get; set; }
+}
+
+public class ChangedItem: Item
+{
+ public SqlChangeOperation Operation { get; set; }
+ public required string Payload { get; set; }
+}
+
+public class SessionProcessor(OpenAIClient openAIClient, SqlConnection conn, ILogger logger)
+{
+ private readonly string _openAIDeploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_EMBEDDINGS_DEPLOYMENT_NAME") ?? "embeddings";
+
+ [Function(nameof(SessionTrigger))]
+ public async Task SessionTrigger(
+ [SqlTrigger("[web].[sessions]", "AZURE_SQL_CONNECTION_STRING")]
+ IReadOnlyList> changes
+ )
+ {
+ var ci = from c in changes
+ where c.Operation != SqlChangeOperation.Delete
+ where c.Item.RequireEmbeddingsUpdate == true
+ select new ChangedItem() {
+ Id = c.Item.Id,
+ Operation = c.Operation,
+ Payload = c.Item.Title + ':' + c.Item.Abstract
+ };
+
+ await ProcessChanges(ci, "web.sessions", "web.upsert_session_embeddings", logger);
+ }
+
+ [Function(nameof(SpeakerTrigger))]
+ public async Task SpeakerTrigger(
+ [SqlTrigger("[web].[speakers]", "AZURE_SQL_CONNECTION_STRING")]
+ IReadOnlyList> changes
+ )
+ {
+ var ci = from c in changes
+ where c.Operation != SqlChangeOperation.Delete
+ where c.Item.RequireEmbeddingsUpdate == true
+ select new ChangedItem() {
+ Id = c.Item.Id,
+ Operation = c.Operation,
+ Payload = c.Item.FullName ?? "",
+ RequireEmbeddingsUpdate = c.Item.RequireEmbeddingsUpdate
+ };
+
+ await ProcessChanges(ci, "web.speakers", "web.upsert_speaker_embeddings", logger);
+ }
+
+ private async Task ProcessChanges(IEnumerable changes, string referenceTable, string upsertStoredProcedure, ILogger logger)
+ {
+ var ct = changes.Count();
+ if (ct == 0) {
+ logger.LogInformation($"No useful changes detected on {referenceTable} table.");
+ return;
+ }
+
+ logger.LogInformation($"There are {ct} changes that requires processing on table {referenceTable}.");
+
+ foreach (var change in changes)
+ {
+ logger.LogInformation($"[{referenceTable}:{change.Id}] Processing change for operation: " + change.Operation.ToString());
+
+ var attempts = 0;
+ var embeddingsReceived = false;
+ while (attempts < 3)
+ {
+ attempts++;
+
+ logger.LogInformation($"[{referenceTable}:{change.Id}] Attempt {attempts}/3 to get embeddings.");
+
+ var response = await openAIClient.GetEmbeddingsAsync(
+ new EmbeddingsOptions(_openAIDeploymentName, [change.Payload])
+ );
+
+ var e = response.Value.Data[0].Embedding;
+ await conn.ExecuteAsync(
+ upsertStoredProcedure,
+ commandType: CommandType.StoredProcedure,
+ param: new
+ {
+ @id = change.Id,
+ @embeddings = JsonSerializer.Serialize(e)
+ });
+ embeddingsReceived = true;
+
+ logger.LogInformation($"[{referenceTable}:{change.Id}] Done.");
+
+ break;
+ }
+ if (!embeddingsReceived)
+ {
+ logger.LogInformation($"[{referenceTable}:{change.Id}] Failed to get embeddings.");
+ }
+ }
+ }
+}
+
diff --git a/func/host.json b/func/host.json
new file mode 100644
index 0000000..f93b3ee
--- /dev/null
+++ b/func/host.json
@@ -0,0 +1,12 @@
+{
+ "version": "2.0",
+ "logging": {
+ "applicationInsights": {
+ "samplingSettings": {
+ "isEnabled": true,
+ "excludedTypes": "Request"
+ },
+ "enableLiveMetricsFilters": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/func/local.settings.json.sample b/func/local.settings.json.sample
new file mode 100644
index 0000000..adc93a0
--- /dev/null
+++ b/func/local.settings.json.sample
@@ -0,0 +1,12 @@
+{
+ "IsEncrypted": false,
+ "Values": {
+ "AzureWebJobsStorage": "UseDevelopmentStorage=true",
+ "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated",
+ "AZURE_SQL_CONNECTION_STRING": "Server=.database.windows.net;Initial Catalog=;Persist Security Info=False;User ID=session_recommender_app;Password=unEno!h5!&*KP420xds&@P901afb$^M;MultipleActiveResultSets=False;Encrypt=True;Connection Timeout=30;",
+ "AZURE_OPENAI_ENDPOINT": "https://.openai.azure.com/",
+ "AZURE_OPENAI_KEY": "",
+ "AZURE_OPENAI_EMBEDDINGS_DEPLOYMENT_NAME": "embeddings",
+ "AZURE_OPENAI_GPT_DEPLOYMENT_NAME": "gpt"
+ }
+}
\ No newline at end of file
diff --git a/infra/abbreviations.json b/infra/abbreviations.json
new file mode 100644
index 0000000..0126e6d
--- /dev/null
+++ b/infra/abbreviations.json
@@ -0,0 +1,136 @@
+{
+ "analysisServicesServers": "as",
+ "apiManagementService": "apim-",
+ "appConfigurationConfigurationStores": "appcs-",
+ "appManagedEnvironments": "cae-",
+ "appContainerApps": "ca-",
+ "authorizationPolicyDefinitions": "policy-",
+ "automationAutomationAccounts": "aa-",
+ "blueprintBlueprints": "bp-",
+ "blueprintBlueprintsArtifacts": "bpa-",
+ "cacheRedis": "redis-",
+ "cdnProfiles": "cdnp-",
+ "cdnProfilesEndpoints": "cdne-",
+ "cognitiveServicesAccounts": "cog-",
+ "cognitiveServicesFormRecognizer": "cog-fr-",
+ "cognitiveServicesTextAnalytics": "cog-ta-",
+ "computeAvailabilitySets": "avail-",
+ "computeCloudServices": "cld-",
+ "computeDiskEncryptionSets": "des",
+ "computeDisks": "disk",
+ "computeDisksOs": "osdisk",
+ "computeGalleries": "gal",
+ "computeSnapshots": "snap-",
+ "computeVirtualMachines": "vm",
+ "computeVirtualMachineScaleSets": "vmss-",
+ "containerInstanceContainerGroups": "ci",
+ "containerRegistryRegistries": "cr",
+ "containerServiceManagedClusters": "aks-",
+ "databricksWorkspaces": "dbw-",
+ "dataFactoryFactories": "adf-",
+ "dataLakeAnalyticsAccounts": "dla",
+ "dataLakeStoreAccounts": "dls",
+ "dataMigrationServices": "dms-",
+ "dBforMySQLServers": "mysql-",
+ "dBforPostgreSQLServers": "psql-",
+ "devicesIotHubs": "iot-",
+ "devicesProvisioningServices": "provs-",
+ "devicesProvisioningServicesCertificates": "pcert-",
+ "documentDBDatabaseAccounts": "cosmos-",
+ "eventGridDomains": "evgd-",
+ "eventGridDomainsTopics": "evgt-",
+ "eventGridEventSubscriptions": "evgs-",
+ "eventHubNamespaces": "evhns-",
+ "eventHubNamespacesEventHubs": "evh-",
+ "hdInsightClustersHadoop": "hadoop-",
+ "hdInsightClustersHbase": "hbase-",
+ "hdInsightClustersKafka": "kafka-",
+ "hdInsightClustersMl": "mls-",
+ "hdInsightClustersSpark": "spark-",
+ "hdInsightClustersStorm": "storm-",
+ "hybridComputeMachines": "arcs-",
+ "insightsActionGroups": "ag-",
+ "insightsComponents": "appi-",
+ "keyVaultVaults": "kv-",
+ "kubernetesConnectedClusters": "arck",
+ "kustoClusters": "dec",
+ "kustoClustersDatabases": "dedb",
+ "logicIntegrationAccounts": "ia-",
+ "logicWorkflows": "logic-",
+ "machineLearningServicesWorkspaces": "mlw-",
+ "managedIdentityUserAssignedIdentities": "id-",
+ "managementManagementGroups": "mg-",
+ "migrateAssessmentProjects": "migr-",
+ "networkApplicationGateways": "agw-",
+ "networkApplicationSecurityGroups": "asg-",
+ "networkAzureFirewalls": "afw-",
+ "networkBastionHosts": "bas-",
+ "networkConnections": "con-",
+ "networkDnsZones": "dnsz-",
+ "networkExpressRouteCircuits": "erc-",
+ "networkFirewallPolicies": "afwp-",
+ "networkFirewallPoliciesWebApplication": "waf",
+ "networkFirewallPoliciesRuleGroups": "wafrg",
+ "networkFrontDoors": "fd-",
+ "networkFrontdoorWebApplicationFirewallPolicies": "fdfp-",
+ "networkLoadBalancersExternal": "lbe-",
+ "networkLoadBalancersInternal": "lbi-",
+ "networkLoadBalancersInboundNatRules": "rule-",
+ "networkLocalNetworkGateways": "lgw-",
+ "networkNatGateways": "ng-",
+ "networkNetworkInterfaces": "nic-",
+ "networkNetworkSecurityGroups": "nsg-",
+ "networkNetworkSecurityGroupsSecurityRules": "nsgsr-",
+ "networkNetworkWatchers": "nw-",
+ "networkPrivateDnsZones": "pdnsz-",
+ "networkPrivateLinkServices": "pl-",
+ "networkPublicIPAddresses": "pip-",
+ "networkPublicIPPrefixes": "ippre-",
+ "networkRouteFilters": "rf-",
+ "networkRouteTables": "rt-",
+ "networkRouteTablesRoutes": "udr-",
+ "networkTrafficManagerProfiles": "traf-",
+ "networkVirtualNetworkGateways": "vgw-",
+ "networkVirtualNetworks": "vnet-",
+ "networkVirtualNetworksSubnets": "snet-",
+ "networkVirtualNetworksVirtualNetworkPeerings": "peer-",
+ "networkVirtualWans": "vwan-",
+ "networkVpnGateways": "vpng-",
+ "networkVpnGatewaysVpnConnections": "vcn-",
+ "networkVpnGatewaysVpnSites": "vst-",
+ "notificationHubsNamespaces": "ntfns-",
+ "notificationHubsNamespacesNotificationHubs": "ntf-",
+ "operationalInsightsWorkspaces": "log-",
+ "portalDashboards": "dash-",
+ "powerBIDedicatedCapacities": "pbi-",
+ "purviewAccounts": "pview-",
+ "recoveryServicesVaults": "rsv-",
+ "resourcesResourceGroups": "rg-",
+ "searchSearchServices": "srch-",
+ "serviceBusNamespaces": "sb-",
+ "serviceBusNamespacesQueues": "sbq-",
+ "serviceBusNamespacesTopics": "sbt-",
+ "serviceEndPointPolicies": "se-",
+ "serviceFabricClusters": "sf-",
+ "signalRServiceSignalR": "sigr",
+ "sqlManagedInstances": "sqlmi-",
+ "sqlServers": "sql-",
+ "sqlServersDataWarehouse": "sqldw-",
+ "sqlServersDatabases": "sqldb-",
+ "sqlServersDatabasesStretch": "sqlstrdb-",
+ "storageStorageAccounts": "st",
+ "storageStorageAccountsVm": "stvm",
+ "storSimpleManagers": "ssimp",
+ "streamAnalyticsCluster": "asa-",
+ "synapseWorkspaces": "syn",
+ "synapseWorkspacesAnalyticsWorkspaces": "synw",
+ "synapseWorkspacesSqlPoolsDedicated": "syndp",
+ "synapseWorkspacesSqlPoolsSpark": "synsp",
+ "timeSeriesInsightsEnvironments": "tsi-",
+ "webServerFarms": "plan-",
+ "webSitesAppService": "app-",
+ "webSitesAppServiceEnvironment": "ase-",
+ "webSitesFunctions": "func-",
+ "webStaticSites": "stapp-"
+ }
+
\ No newline at end of file
diff --git a/infra/app/functions.bicep b/infra/app/functions.bicep
new file mode 100644
index 0000000..5b603a0
--- /dev/null
+++ b/infra/app/functions.bicep
@@ -0,0 +1,49 @@
+param functionAppName string
+param location string = resourceGroup().location
+param hostingPlanId string
+param storageAccountName string
+@secure()
+param sqlConnectionString string
+param keyVaultName string
+param tags object = {}
+param applicationInsightsConnectionString string
+param useKeyVault bool
+param keyVaultEndpoint string = ''
+@secure()
+param openAIEndpoint string
+param openAIKeyName string
+param openAIName string
+param openAIEmebddingDeploymentName string = 'embeddings'
+param openAIGPTDeploymentName string = 'gpt'
+
+module functionApp '../core/host/functions.bicep' = {
+ name: 'function1'
+ params: {
+ location: location
+ alwaysOn: false
+ tags: union(tags, { 'azd-service-name': 'functionapp' })
+ kind: 'functionapp'
+ keyVaultName: keyVaultName
+ appServicePlanId: hostingPlanId
+ name: functionAppName
+ runtimeName: 'dotnet-isolated'
+ runtimeVersion: '8.0'
+ storageAccountName: storageAccountName
+ appSettings: {
+ WEBSITE_CONTENTSHARE: toLower(functionAppName)
+ WEBSITE_CONTENTAZUREFILECONNECTIONSTRING: 'DefaultEndpointsProtocol=https;AccountName=${storageAccountName};EndpointSuffix=${environment().suffixes.storage};AccountKey=${listKeys(resourceId(subscription().subscriptionId, resourceGroup().name, 'Microsoft.Storage/storageAccounts', storageAccountName), '2022-05-01').keys[0].value}'
+ APPLICATIONINSIGHTS_CONNECTION_STRING: applicationInsightsConnectionString
+ AZURE_SQL_CONNECTION_STRING: sqlConnectionString
+ AZURE_OPENAI_ENDPOINT: openAIEndpoint
+ AZURE_OPENAI_KEY: useKeyVault ? openAIKeyName : listKeys(resourceId(subscription().subscriptionId, resourceGroup().name, 'Microsoft.CognitiveServices/accounts', openAIName), '2023-05-01').key1
+ AZURE_OPENAI_EMBEDDINGS_DEPLOYMENT_NAME: openAIEmebddingDeploymentName
+ AZURE_OPENAI_GPT_DEPLOYMENT_NAME: openAIGPTDeploymentName
+ AZURE_KEY_VAULT_ENDPOINT: useKeyVault ? keyVaultEndpoint : ''
+ }
+ }
+}
+
+output functionAppResourceId string = functionApp.outputs.functionAppResourceId
+output name string = functionApp.outputs.name
+output uri string = functionApp.outputs.uri
+output identityPrincipalId string = functionApp.outputs.identityPrincipalId
diff --git a/infra/app/openai.bicep b/infra/app/openai.bicep
new file mode 100644
index 0000000..f9af5d8
--- /dev/null
+++ b/infra/app/openai.bicep
@@ -0,0 +1,57 @@
+metadata description = 'Creates an Azure Cognitive Services instance.'
+param name string
+param location string = resourceGroup().location
+param tags object = {}
+@description('The custom subdomain name used to access the API. Defaults to the value of the name parameter.')
+param customSubDomainName string = name
+param deployments array = []
+param kind string = 'OpenAI'
+param publicNetworkAccess string = 'Enabled'
+param sku object = {
+ name: 'S0'
+}
+param keyVaultName string
+param useKeyVault bool
+
+resource account 'Microsoft.CognitiveServices/accounts@2023-05-01' = {
+ name: name
+ location: location
+ tags: tags
+ kind: kind
+ properties: {
+ customSubDomainName: customSubDomainName
+ publicNetworkAccess: publicNetworkAccess
+ }
+ sku: sku
+}
+
+@batchSize(1)
+resource deployment 'Microsoft.CognitiveServices/accounts/deployments@2023-05-01' = [for deployment in deployments: {
+ parent: account
+ name: deployment.name
+ properties: {
+ model: deployment.model
+ raiPolicyName: contains(deployment, 'raiPolicyName') ? deployment.raiPolicyName : null
+ }
+ sku: contains(deployment, 'sku') ? deployment.sku : {
+ name: 'Standard'
+ capacity: 20
+ }
+}]
+
+resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' existing = if (useKeyVault) {
+ name: keyVaultName
+}
+
+resource openAIKey 'Microsoft.KeyVault/vaults/secrets@2022-07-01' = if (useKeyVault) {
+ parent: keyVault
+ name: 'openAIKey'
+ properties: {
+ value: account.listKeys().key1
+ }
+}
+
+output endpoint string = account.properties.endpoint
+output id string = account.id
+output name string = account.name
+output openAIKeyName string = openAIKey.name
diff --git a/infra/app/sqlserver.bicep b/infra/app/sqlserver.bicep
new file mode 100644
index 0000000..82d662f
--- /dev/null
+++ b/infra/app/sqlserver.bicep
@@ -0,0 +1,114 @@
+metadata description = 'Creates an Azure SQL Server instance.'
+param name string
+param location string = resourceGroup().location
+param tags object = {}
+param databaseName string
+param principalId string
+param connectionStringKey string = 'AZURE-SQL-CONNECTION-STRING'
+
+param sqlAdmin string = 'sqlAdmin'
+@secure()
+param sqlAdminPassword string
+
+param appUser string = 'session_recommender_app'
+@secure()
+param appUserPassword string
+
+@secure()
+param openAIEndpoint string
+param openAIDeploymentName string
+param openAIServiceName string
+
+
+resource sqlServer 'Microsoft.Sql/servers@2022-05-01-preview' = {
+ name: name
+ location: location
+ tags: tags
+ properties: {
+ version: '12.0'
+ minimalTlsVersion: '1.2'
+ publicNetworkAccess: 'Enabled'
+ administratorLogin: sqlAdmin
+ administratorLoginPassword: sqlAdminPassword
+ }
+
+ resource database 'databases' = {
+ name: databaseName
+ location: location
+ }
+
+ resource firewall 'firewallRules' = {
+ name: 'Azure Services'
+ properties: {
+ // Allow all clients
+ // Note: range [0.0.0.0-0.0.0.0] means "allow all Azure-hosted clients only".
+ // This is not sufficient, because we also want to allow direct access from developer machine, for debugging purposes.
+ startIpAddress: '0.0.0.0'
+ endIpAddress: '0.0.0.0'
+ }
+ }
+
+ resource symbolicname 'administrators@2022-05-01-preview' = {
+ name: 'ActiveDirectory'
+ properties: {
+ administratorType: 'ActiveDirectory'
+ login: 'EntraAdmin'
+ sid: principalId
+ tenantId: tenant().tenantId
+ }
+ }
+}
+
+resource createDBScript2 'Microsoft.Resources/deploymentScripts@2023-08-01' = {
+ name: '${name}-createDB-script'
+ location: location
+ kind: 'AzurePowerShell'
+ properties: {
+ azPowerShellVersion: '10.0'
+ retentionInterval: 'PT1H' // Retain the script resource for 1 hour after it ends running
+ timeout: 'PT5M' // Five minutes
+ cleanupPreference: 'OnSuccess'
+ environmentVariables: [
+ {
+ name: 'DBNAME'
+ value: databaseName
+ }
+ {
+ name: 'DBSERVER'
+ value: sqlServer.properties.fullyQualifiedDomainName
+ }
+ {
+ name: 'SQLCMDPASSWORD'
+ secureValue: sqlAdminPassword
+ }
+ {
+ name: 'SQLADMIN'
+ value: sqlAdmin
+ }
+ {
+ name: 'OPEN_AI_ENDPOINT'
+ value: openAIEndpoint
+ }
+ {
+ name: 'OPEN_AI_DEPLOYMENT'
+ value: openAIDeploymentName
+ }
+ {
+ name: 'OPEN_AI_KEY'
+ secureValue: listKeys(resourceId(subscription().subscriptionId, resourceGroup().name, 'Microsoft.CognitiveServices/accounts', openAIServiceName), '2023-05-01').key1
+ }
+ {
+ name: 'APP_USER_PASSWORD'
+ secureValue: appUserPassword
+ }
+ ]
+ scriptContent: loadTextContent('../../database/setup-database.ps1')
+ }
+}
+
+var connectionString = 'Server=${sqlServer.properties.fullyQualifiedDomainName}; Database=${sqlServer::database.name}; User=${appUser}'
+output connectionStringKey string = connectionStringKey
+output connectionString string = connectionString
+output databaseName string = sqlServer::database.name
+output name string = sqlServer.name
+output id string = sqlServer.id
diff --git a/infra/app/staticwebapp.bicep b/infra/app/staticwebapp.bicep
new file mode 100644
index 0000000..c84003e
--- /dev/null
+++ b/infra/app/staticwebapp.bicep
@@ -0,0 +1,39 @@
+metadata description = 'Creates an Azure Static Web Apps instance.'
+param name string
+param location string = resourceGroup().location
+param tags object = {}
+param sku object = {
+ name: 'Standard'
+ tier: 'Standard'
+}
+param sqlServerLocation string
+param sqlServerId string
+@secure()
+param sqlConnectionString string
+param apiResourceId string
+
+resource web 'Microsoft.Web/staticSites@2022-09-01' = {
+ name: name
+ location: location
+ tags: tags
+ properties: {}
+ sku: sku
+ resource apifunc 'linkedBackends@2022-09-01' = {
+ name: 'default'
+ properties: {
+ backendResourceId: apiResourceId
+ region: location
+ }
+ }
+ resource dbconn 'databaseConnections@2022-09-01' = {
+ name: 'default'
+ properties: {
+ connectionString: sqlConnectionString
+ region: sqlServerLocation
+ resourceId: sqlServerId
+ }
+ }
+}
+
+output name string = web.name
+output uri string = 'https://${web.properties.defaultHostname}'
diff --git a/infra/core/host/appservice-appsettings.bicep b/infra/core/host/appservice-appsettings.bicep
new file mode 100644
index 0000000..f4b22f8
--- /dev/null
+++ b/infra/core/host/appservice-appsettings.bicep
@@ -0,0 +1,17 @@
+metadata description = 'Updates app settings for an Azure App Service.'
+@description('The name of the app service resource within the current resource group scope')
+param name string
+
+@description('The app settings to be applied to the app service')
+@secure()
+param appSettings object
+
+resource appService 'Microsoft.Web/sites@2022-03-01' existing = {
+ name: name
+}
+
+resource settings 'Microsoft.Web/sites/config@2022-03-01' = {
+ name: 'appsettings'
+ parent: appService
+ properties: appSettings
+}
diff --git a/infra/core/host/appservice.bicep b/infra/core/host/appservice.bicep
new file mode 100644
index 0000000..6580cd2
--- /dev/null
+++ b/infra/core/host/appservice.bicep
@@ -0,0 +1,124 @@
+metadata description = 'Creates an Azure App Service in an existing Azure App Service plan.'
+param name string
+param location string = resourceGroup().location
+param tags object = {}
+
+// Reference Properties
+param applicationInsightsName string = ''
+param appServicePlanId string
+param keyVaultName string = ''
+param managedIdentity bool = !empty(keyVaultName)
+
+// Runtime Properties
+@allowed([
+ 'dotnet', 'dotnetcore', 'dotnet-isolated', 'node', 'python', 'java', 'powershell', 'custom'
+])
+param runtimeName string
+param runtimeNameAndVersion string = '${runtimeName}|${runtimeVersion}'
+param runtimeVersion string
+
+// Microsoft.Web/sites Properties
+param kind string = 'app,linux'
+
+// Microsoft.Web/sites/config
+param allowedOrigins array = []
+param alwaysOn bool = true
+param appCommandLine string = ''
+@secure()
+param appSettings object = {}
+param clientAffinityEnabled bool = false
+param enableOryxBuild bool = contains(kind, 'linux')
+param functionAppScaleLimit int = -1
+param linuxFxVersion string = runtimeNameAndVersion
+param minimumElasticInstanceCount int = -1
+param numberOfWorkers int = -1
+param scmDoBuildDuringDeployment bool = false
+param use32BitWorkerProcess bool = false
+param ftpsState string = 'FtpsOnly'
+param healthCheckPath string = ''
+
+resource appService 'Microsoft.Web/sites@2022-03-01' = {
+ name: name
+ location: location
+ tags: tags
+ kind: kind
+ properties: {
+ serverFarmId: appServicePlanId
+ siteConfig: {
+ linuxFxVersion: linuxFxVersion
+ alwaysOn: alwaysOn
+ ftpsState: ftpsState
+ minTlsVersion: '1.2'
+ appCommandLine: appCommandLine
+ numberOfWorkers: numberOfWorkers != -1 ? numberOfWorkers : null
+ minimumElasticInstanceCount: minimumElasticInstanceCount != -1 ? minimumElasticInstanceCount : null
+ use32BitWorkerProcess: use32BitWorkerProcess
+ functionAppScaleLimit: functionAppScaleLimit != -1 ? functionAppScaleLimit : null
+ healthCheckPath: healthCheckPath
+ cors: {
+ allowedOrigins: union([ 'https://portal.azure.com', 'https://ms.portal.azure.com' ], allowedOrigins)
+ }
+ }
+ clientAffinityEnabled: clientAffinityEnabled
+ httpsOnly: true
+ }
+
+ identity: { type: managedIdentity ? 'SystemAssigned' : 'None' }
+
+ resource basicPublishingCredentialsPoliciesFtp 'basicPublishingCredentialsPolicies' = {
+ name: 'ftp'
+ properties: {
+ allow: false
+ }
+ }
+
+ resource basicPublishingCredentialsPoliciesScm 'basicPublishingCredentialsPolicies' = {
+ name: 'scm'
+ properties: {
+ allow: false
+ }
+ }
+}
+
+// Updates to the single Microsoft.sites/web/config resources that need to be performed sequentially
+// sites/web/config 'appsettings'
+module configAppSettings 'appservice-appsettings.bicep' = {
+ name: '${name}-appSettings'
+ params: {
+ name: appService.name
+ appSettings: union(appSettings,
+ {
+ SCM_DO_BUILD_DURING_DEPLOYMENT: string(scmDoBuildDuringDeployment)
+ ENABLE_ORYX_BUILD: string(enableOryxBuild)
+ },
+ runtimeName == 'python' && appCommandLine == '' ? { PYTHON_ENABLE_GUNICORN_MULTIWORKERS: 'true'} : {},
+ !empty(applicationInsightsName) ? { APPLICATIONINSIGHTS_CONNECTION_STRING: applicationInsights.properties.ConnectionString } : {},
+ !empty(keyVaultName) ? { AZURE_KEY_VAULT_ENDPOINT: keyVault.properties.vaultUri } : {})
+ }
+}
+
+// sites/web/config 'logs'
+resource configLogs 'Microsoft.Web/sites/config@2022-03-01' = {
+ name: 'logs'
+ parent: appService
+ properties: {
+ applicationLogs: { fileSystem: { level: 'Verbose' } }
+ detailedErrorMessages: { enabled: true }
+ failedRequestsTracing: { enabled: true }
+ httpLogs: { fileSystem: { enabled: true, retentionInDays: 1, retentionInMb: 35 } }
+ }
+ dependsOn: [configAppSettings]
+}
+
+resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' existing = if (!(empty(keyVaultName))) {
+ name: keyVaultName
+}
+
+resource applicationInsights 'Microsoft.Insights/components@2020-02-02' existing = if (!empty(applicationInsightsName)) {
+ name: applicationInsightsName
+}
+
+output identityPrincipalId string = managedIdentity ? appService.identity.principalId : ''
+output name string = appService.name
+output uri string = 'https://${appService.properties.defaultHostName}'
+output functionAppResourceId string = appService.id
diff --git a/infra/core/host/appserviceplan.bicep b/infra/core/host/appserviceplan.bicep
new file mode 100644
index 0000000..2e37e04
--- /dev/null
+++ b/infra/core/host/appserviceplan.bicep
@@ -0,0 +1,22 @@
+metadata description = 'Creates an Azure App Service plan.'
+param name string
+param location string = resourceGroup().location
+param tags object = {}
+
+param kind string = ''
+param reserved bool = true
+param sku object
+
+resource appServicePlan 'Microsoft.Web/serverfarms@2022-03-01' = {
+ name: name
+ location: location
+ tags: tags
+ sku: sku
+ kind: kind
+ properties: {
+ reserved: reserved
+ }
+}
+
+output id string = appServicePlan.id
+output name string = appServicePlan.name
diff --git a/infra/core/host/functions.bicep b/infra/core/host/functions.bicep
new file mode 100644
index 0000000..e57fff7
--- /dev/null
+++ b/infra/core/host/functions.bicep
@@ -0,0 +1,87 @@
+metadata description = 'Creates an Azure Function in an existing Azure App Service plan.'
+param name string
+param location string = resourceGroup().location
+param tags object = {}
+
+// Reference Properties
+param applicationInsightsName string = ''
+param appServicePlanId string
+param keyVaultName string = ''
+param managedIdentity bool = !empty(keyVaultName)
+param storageAccountName string
+
+// Runtime Properties
+@allowed([
+ 'dotnet', 'dotnetcore', 'dotnet-isolated', 'node', 'python', 'java', 'powershell', 'custom'
+])
+param runtimeName string
+param runtimeNameAndVersion string = '${runtimeName}|${runtimeVersion}'
+param runtimeVersion string
+
+// Function Settings
+@allowed([
+ '~4', '~3', '~2', '~1'
+])
+param extensionVersion string = '~4'
+
+// Microsoft.Web/sites Properties
+param kind string = 'functionapp,linux'
+
+// Microsoft.Web/sites/config
+param allowedOrigins array = []
+param alwaysOn bool = true
+param appCommandLine string = ''
+@secure()
+param appSettings object = {}
+param clientAffinityEnabled bool = false
+param enableOryxBuild bool = contains(kind, 'linux')
+param functionAppScaleLimit int = -1
+param linuxFxVersion string = runtimeNameAndVersion
+param minimumElasticInstanceCount int = -1
+param numberOfWorkers int = -1
+param scmDoBuildDuringDeployment bool = true
+param use32BitWorkerProcess bool = false
+param healthCheckPath string = ''
+
+module functions 'appservice.bicep' = {
+ name: '${name}-functions'
+ params: {
+ name: name
+ location: location
+ tags: tags
+ allowedOrigins: allowedOrigins
+ alwaysOn: alwaysOn
+ appCommandLine: appCommandLine
+ applicationInsightsName: applicationInsightsName
+ appServicePlanId: appServicePlanId
+ appSettings: union(appSettings, {
+ AzureWebJobsStorage: 'DefaultEndpointsProtocol=https;AccountName=${storage.name};AccountKey=${storage.listKeys().keys[0].value};EndpointSuffix=${environment().suffixes.storage}'
+ FUNCTIONS_EXTENSION_VERSION: extensionVersion
+ FUNCTIONS_WORKER_RUNTIME: runtimeName
+ })
+ clientAffinityEnabled: clientAffinityEnabled
+ enableOryxBuild: enableOryxBuild
+ functionAppScaleLimit: functionAppScaleLimit
+ healthCheckPath: healthCheckPath
+ keyVaultName: keyVaultName
+ kind: kind
+ linuxFxVersion: linuxFxVersion
+ managedIdentity: managedIdentity
+ minimumElasticInstanceCount: minimumElasticInstanceCount
+ numberOfWorkers: numberOfWorkers
+ runtimeName: runtimeName
+ runtimeVersion: runtimeVersion
+ runtimeNameAndVersion: runtimeNameAndVersion
+ scmDoBuildDuringDeployment: scmDoBuildDuringDeployment
+ use32BitWorkerProcess: use32BitWorkerProcess
+ }
+}
+
+resource storage 'Microsoft.Storage/storageAccounts@2021-09-01' existing = {
+ name: storageAccountName
+}
+
+output identityPrincipalId string = managedIdentity ? functions.outputs.identityPrincipalId : ''
+output name string = functions.outputs.name
+output uri string = functions.outputs.uri
+output functionAppResourceId string = functions.outputs.functionAppResourceId
diff --git a/infra/core/monitor/applicationinsights-dashboard.bicep b/infra/core/monitor/applicationinsights-dashboard.bicep
new file mode 100644
index 0000000..d082e66
--- /dev/null
+++ b/infra/core/monitor/applicationinsights-dashboard.bicep
@@ -0,0 +1,1236 @@
+metadata description = 'Creates a dashboard for an Application Insights instance.'
+param name string
+param applicationInsightsName string
+param location string = resourceGroup().location
+param tags object = {}
+
+// 2020-09-01-preview because that is the latest valid version
+resource applicationInsightsDashboard 'Microsoft.Portal/dashboards@2020-09-01-preview' = {
+ name: name
+ location: location
+ tags: tags
+ properties: {
+ lenses: [
+ {
+ order: 0
+ parts: [
+ {
+ position: {
+ x: 0
+ y: 0
+ colSpan: 2
+ rowSpan: 1
+ }
+ metadata: {
+ inputs: [
+ {
+ name: 'id'
+ value: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+ }
+ {
+ name: 'Version'
+ value: '1.0'
+ }
+ ]
+ #disable-next-line BCP036
+ type: 'Extension/AppInsightsExtension/PartType/AspNetOverviewPinnedPart'
+ asset: {
+ idInputName: 'id'
+ type: 'ApplicationInsights'
+ }
+ defaultMenuItemId: 'overview'
+ }
+ }
+ {
+ position: {
+ x: 2
+ y: 0
+ colSpan: 1
+ rowSpan: 1
+ }
+ metadata: {
+ inputs: [
+ {
+ name: 'ComponentId'
+ value: {
+ Name: applicationInsights.name
+ SubscriptionId: subscription().subscriptionId
+ ResourceGroup: resourceGroup().name
+ }
+ }
+ {
+ name: 'Version'
+ value: '1.0'
+ }
+ ]
+ #disable-next-line BCP036
+ type: 'Extension/AppInsightsExtension/PartType/ProactiveDetectionAsyncPart'
+ asset: {
+ idInputName: 'ComponentId'
+ type: 'ApplicationInsights'
+ }
+ defaultMenuItemId: 'ProactiveDetection'
+ }
+ }
+ {
+ position: {
+ x: 3
+ y: 0
+ colSpan: 1
+ rowSpan: 1
+ }
+ metadata: {
+ inputs: [
+ {
+ name: 'ComponentId'
+ value: {
+ Name: applicationInsights.name
+ SubscriptionId: subscription().subscriptionId
+ ResourceGroup: resourceGroup().name
+ }
+ }
+ {
+ name: 'ResourceId'
+ value: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+ }
+ ]
+ #disable-next-line BCP036
+ type: 'Extension/AppInsightsExtension/PartType/QuickPulseButtonSmallPart'
+ asset: {
+ idInputName: 'ComponentId'
+ type: 'ApplicationInsights'
+ }
+ }
+ }
+ {
+ position: {
+ x: 4
+ y: 0
+ colSpan: 1
+ rowSpan: 1
+ }
+ metadata: {
+ inputs: [
+ {
+ name: 'ComponentId'
+ value: {
+ Name: applicationInsights.name
+ SubscriptionId: subscription().subscriptionId
+ ResourceGroup: resourceGroup().name
+ }
+ }
+ {
+ name: 'TimeContext'
+ value: {
+ durationMs: 86400000
+ endTime: null
+ createdTime: '2018-05-04T01:20:33.345Z'
+ isInitialTime: true
+ grain: 1
+ useDashboardTimeRange: false
+ }
+ }
+ {
+ name: 'Version'
+ value: '1.0'
+ }
+ ]
+ #disable-next-line BCP036
+ type: 'Extension/AppInsightsExtension/PartType/AvailabilityNavButtonPart'
+ asset: {
+ idInputName: 'ComponentId'
+ type: 'ApplicationInsights'
+ }
+ }
+ }
+ {
+ position: {
+ x: 5
+ y: 0
+ colSpan: 1
+ rowSpan: 1
+ }
+ metadata: {
+ inputs: [
+ {
+ name: 'ComponentId'
+ value: {
+ Name: applicationInsights.name
+ SubscriptionId: subscription().subscriptionId
+ ResourceGroup: resourceGroup().name
+ }
+ }
+ {
+ name: 'TimeContext'
+ value: {
+ durationMs: 86400000
+ endTime: null
+ createdTime: '2018-05-08T18:47:35.237Z'
+ isInitialTime: true
+ grain: 1
+ useDashboardTimeRange: false
+ }
+ }
+ {
+ name: 'ConfigurationId'
+ value: '78ce933e-e864-4b05-a27b-71fd55a6afad'
+ }
+ ]
+ #disable-next-line BCP036
+ type: 'Extension/AppInsightsExtension/PartType/AppMapButtonPart'
+ asset: {
+ idInputName: 'ComponentId'
+ type: 'ApplicationInsights'
+ }
+ }
+ }
+ {
+ position: {
+ x: 0
+ y: 1
+ colSpan: 3
+ rowSpan: 1
+ }
+ metadata: {
+ inputs: []
+ type: 'Extension/HubsExtension/PartType/MarkdownPart'
+ settings: {
+ content: {
+ settings: {
+ content: '# Usage'
+ title: ''
+ subtitle: ''
+ }
+ }
+ }
+ }
+ }
+ {
+ position: {
+ x: 3
+ y: 1
+ colSpan: 1
+ rowSpan: 1
+ }
+ metadata: {
+ inputs: [
+ {
+ name: 'ComponentId'
+ value: {
+ Name: applicationInsights.name
+ SubscriptionId: subscription().subscriptionId
+ ResourceGroup: resourceGroup().name
+ }
+ }
+ {
+ name: 'TimeContext'
+ value: {
+ durationMs: 86400000
+ endTime: null
+ createdTime: '2018-05-04T01:22:35.782Z'
+ isInitialTime: true
+ grain: 1
+ useDashboardTimeRange: false
+ }
+ }
+ ]
+ #disable-next-line BCP036
+ type: 'Extension/AppInsightsExtension/PartType/UsageUsersOverviewPart'
+ asset: {
+ idInputName: 'ComponentId'
+ type: 'ApplicationInsights'
+ }
+ }
+ }
+ {
+ position: {
+ x: 4
+ y: 1
+ colSpan: 3
+ rowSpan: 1
+ }
+ metadata: {
+ inputs: []
+ type: 'Extension/HubsExtension/PartType/MarkdownPart'
+ settings: {
+ content: {
+ settings: {
+ content: '# Reliability'
+ title: ''
+ subtitle: ''
+ }
+ }
+ }
+ }
+ }
+ {
+ position: {
+ x: 7
+ y: 1
+ colSpan: 1
+ rowSpan: 1
+ }
+ metadata: {
+ inputs: [
+ {
+ name: 'ResourceId'
+ value: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+ }
+ {
+ name: 'DataModel'
+ value: {
+ version: '1.0.0'
+ timeContext: {
+ durationMs: 86400000
+ createdTime: '2018-05-04T23:42:40.072Z'
+ isInitialTime: false
+ grain: 1
+ useDashboardTimeRange: false
+ }
+ }
+ isOptional: true
+ }
+ {
+ name: 'ConfigurationId'
+ value: '8a02f7bf-ac0f-40e1-afe9-f0e72cfee77f'
+ isOptional: true
+ }
+ ]
+ #disable-next-line BCP036
+ type: 'Extension/AppInsightsExtension/PartType/CuratedBladeFailuresPinnedPart'
+ isAdapter: true
+ asset: {
+ idInputName: 'ResourceId'
+ type: 'ApplicationInsights'
+ }
+ defaultMenuItemId: 'failures'
+ }
+ }
+ {
+ position: {
+ x: 8
+ y: 1
+ colSpan: 3
+ rowSpan: 1
+ }
+ metadata: {
+ inputs: []
+ type: 'Extension/HubsExtension/PartType/MarkdownPart'
+ settings: {
+ content: {
+ settings: {
+ content: '# Responsiveness\r\n'
+ title: ''
+ subtitle: ''
+ }
+ }
+ }
+ }
+ }
+ {
+ position: {
+ x: 11
+ y: 1
+ colSpan: 1
+ rowSpan: 1
+ }
+ metadata: {
+ inputs: [
+ {
+ name: 'ResourceId'
+ value: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+ }
+ {
+ name: 'DataModel'
+ value: {
+ version: '1.0.0'
+ timeContext: {
+ durationMs: 86400000
+ createdTime: '2018-05-04T23:43:37.804Z'
+ isInitialTime: false
+ grain: 1
+ useDashboardTimeRange: false
+ }
+ }
+ isOptional: true
+ }
+ {
+ name: 'ConfigurationId'
+ value: '2a8ede4f-2bee-4b9c-aed9-2db0e8a01865'
+ isOptional: true
+ }
+ ]
+ #disable-next-line BCP036
+ type: 'Extension/AppInsightsExtension/PartType/CuratedBladePerformancePinnedPart'
+ isAdapter: true
+ asset: {
+ idInputName: 'ResourceId'
+ type: 'ApplicationInsights'
+ }
+ defaultMenuItemId: 'performance'
+ }
+ }
+ {
+ position: {
+ x: 12
+ y: 1
+ colSpan: 3
+ rowSpan: 1
+ }
+ metadata: {
+ inputs: []
+ type: 'Extension/HubsExtension/PartType/MarkdownPart'
+ settings: {
+ content: {
+ settings: {
+ content: '# Browser'
+ title: ''
+ subtitle: ''
+ }
+ }
+ }
+ }
+ }
+ {
+ position: {
+ x: 15
+ y: 1
+ colSpan: 1
+ rowSpan: 1
+ }
+ metadata: {
+ inputs: [
+ {
+ name: 'ComponentId'
+ value: {
+ Name: applicationInsights.name
+ SubscriptionId: subscription().subscriptionId
+ ResourceGroup: resourceGroup().name
+ }
+ }
+ {
+ name: 'MetricsExplorerJsonDefinitionId'
+ value: 'BrowserPerformanceTimelineMetrics'
+ }
+ {
+ name: 'TimeContext'
+ value: {
+ durationMs: 86400000
+ createdTime: '2018-05-08T12:16:27.534Z'
+ isInitialTime: false
+ grain: 1
+ useDashboardTimeRange: false
+ }
+ }
+ {
+ name: 'CurrentFilter'
+ value: {
+ eventTypes: [
+ 4
+ 1
+ 3
+ 5
+ 2
+ 6
+ 13
+ ]
+ typeFacets: {}
+ isPermissive: false
+ }
+ }
+ {
+ name: 'id'
+ value: {
+ Name: applicationInsights.name
+ SubscriptionId: subscription().subscriptionId
+ ResourceGroup: resourceGroup().name
+ }
+ }
+ {
+ name: 'Version'
+ value: '1.0'
+ }
+ ]
+ #disable-next-line BCP036
+ type: 'Extension/AppInsightsExtension/PartType/MetricsExplorerBladePinnedPart'
+ asset: {
+ idInputName: 'ComponentId'
+ type: 'ApplicationInsights'
+ }
+ defaultMenuItemId: 'browser'
+ }
+ }
+ {
+ position: {
+ x: 0
+ y: 2
+ colSpan: 4
+ rowSpan: 3
+ }
+ metadata: {
+ inputs: [
+ {
+ name: 'options'
+ value: {
+ chart: {
+ metrics: [
+ {
+ resourceMetadata: {
+ id: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+ }
+ name: 'sessions/count'
+ aggregationType: 5
+ namespace: 'microsoft.insights/components/kusto'
+ metricVisualization: {
+ displayName: 'Sessions'
+ color: '#47BDF5'
+ }
+ }
+ {
+ resourceMetadata: {
+ id: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+ }
+ name: 'users/count'
+ aggregationType: 5
+ namespace: 'microsoft.insights/components/kusto'
+ metricVisualization: {
+ displayName: 'Users'
+ color: '#7E58FF'
+ }
+ }
+ ]
+ title: 'Unique sessions and users'
+ visualization: {
+ chartType: 2
+ legendVisualization: {
+ isVisible: true
+ position: 2
+ hideSubtitle: false
+ }
+ axisVisualization: {
+ x: {
+ isVisible: true
+ axisType: 2
+ }
+ y: {
+ isVisible: true
+ axisType: 1
+ }
+ }
+ }
+ openBladeOnClick: {
+ openBlade: true
+ destinationBlade: {
+ extensionName: 'HubsExtension'
+ bladeName: 'ResourceMenuBlade'
+ parameters: {
+ id: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+ menuid: 'segmentationUsers'
+ }
+ }
+ }
+ }
+ }
+ }
+ {
+ name: 'sharedTimeRange'
+ isOptional: true
+ }
+ ]
+ #disable-next-line BCP036
+ type: 'Extension/HubsExtension/PartType/MonitorChartPart'
+ settings: {}
+ }
+ }
+ {
+ position: {
+ x: 4
+ y: 2
+ colSpan: 4
+ rowSpan: 3
+ }
+ metadata: {
+ inputs: [
+ {
+ name: 'options'
+ value: {
+ chart: {
+ metrics: [
+ {
+ resourceMetadata: {
+ id: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+ }
+ name: 'requests/failed'
+ aggregationType: 7
+ namespace: 'microsoft.insights/components'
+ metricVisualization: {
+ displayName: 'Failed requests'
+ color: '#EC008C'
+ }
+ }
+ ]
+ title: 'Failed requests'
+ visualization: {
+ chartType: 3
+ legendVisualization: {
+ isVisible: true
+ position: 2
+ hideSubtitle: false
+ }
+ axisVisualization: {
+ x: {
+ isVisible: true
+ axisType: 2
+ }
+ y: {
+ isVisible: true
+ axisType: 1
+ }
+ }
+ }
+ openBladeOnClick: {
+ openBlade: true
+ destinationBlade: {
+ extensionName: 'HubsExtension'
+ bladeName: 'ResourceMenuBlade'
+ parameters: {
+ id: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+ menuid: 'failures'
+ }
+ }
+ }
+ }
+ }
+ }
+ {
+ name: 'sharedTimeRange'
+ isOptional: true
+ }
+ ]
+ #disable-next-line BCP036
+ type: 'Extension/HubsExtension/PartType/MonitorChartPart'
+ settings: {}
+ }
+ }
+ {
+ position: {
+ x: 8
+ y: 2
+ colSpan: 4
+ rowSpan: 3
+ }
+ metadata: {
+ inputs: [
+ {
+ name: 'options'
+ value: {
+ chart: {
+ metrics: [
+ {
+ resourceMetadata: {
+ id: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+ }
+ name: 'requests/duration'
+ aggregationType: 4
+ namespace: 'microsoft.insights/components'
+ metricVisualization: {
+ displayName: 'Server response time'
+ color: '#00BCF2'
+ }
+ }
+ ]
+ title: 'Server response time'
+ visualization: {
+ chartType: 2
+ legendVisualization: {
+ isVisible: true
+ position: 2
+ hideSubtitle: false
+ }
+ axisVisualization: {
+ x: {
+ isVisible: true
+ axisType: 2
+ }
+ y: {
+ isVisible: true
+ axisType: 1
+ }
+ }
+ }
+ openBladeOnClick: {
+ openBlade: true
+ destinationBlade: {
+ extensionName: 'HubsExtension'
+ bladeName: 'ResourceMenuBlade'
+ parameters: {
+ id: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+ menuid: 'performance'
+ }
+ }
+ }
+ }
+ }
+ }
+ {
+ name: 'sharedTimeRange'
+ isOptional: true
+ }
+ ]
+ #disable-next-line BCP036
+ type: 'Extension/HubsExtension/PartType/MonitorChartPart'
+ settings: {}
+ }
+ }
+ {
+ position: {
+ x: 12
+ y: 2
+ colSpan: 4
+ rowSpan: 3
+ }
+ metadata: {
+ inputs: [
+ {
+ name: 'options'
+ value: {
+ chart: {
+ metrics: [
+ {
+ resourceMetadata: {
+ id: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+ }
+ name: 'browserTimings/networkDuration'
+ aggregationType: 4
+ namespace: 'microsoft.insights/components'
+ metricVisualization: {
+ displayName: 'Page load network connect time'
+ color: '#7E58FF'
+ }
+ }
+ {
+ resourceMetadata: {
+ id: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+ }
+ name: 'browserTimings/processingDuration'
+ aggregationType: 4
+ namespace: 'microsoft.insights/components'
+ metricVisualization: {
+ displayName: 'Client processing time'
+ color: '#44F1C8'
+ }
+ }
+ {
+ resourceMetadata: {
+ id: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+ }
+ name: 'browserTimings/sendDuration'
+ aggregationType: 4
+ namespace: 'microsoft.insights/components'
+ metricVisualization: {
+ displayName: 'Send request time'
+ color: '#EB9371'
+ }
+ }
+ {
+ resourceMetadata: {
+ id: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+ }
+ name: 'browserTimings/receiveDuration'
+ aggregationType: 4
+ namespace: 'microsoft.insights/components'
+ metricVisualization: {
+ displayName: 'Receiving response time'
+ color: '#0672F1'
+ }
+ }
+ ]
+ title: 'Average page load time breakdown'
+ visualization: {
+ chartType: 3
+ legendVisualization: {
+ isVisible: true
+ position: 2
+ hideSubtitle: false
+ }
+ axisVisualization: {
+ x: {
+ isVisible: true
+ axisType: 2
+ }
+ y: {
+ isVisible: true
+ axisType: 1
+ }
+ }
+ }
+ }
+ }
+ }
+ {
+ name: 'sharedTimeRange'
+ isOptional: true
+ }
+ ]
+ #disable-next-line BCP036
+ type: 'Extension/HubsExtension/PartType/MonitorChartPart'
+ settings: {}
+ }
+ }
+ {
+ position: {
+ x: 0
+ y: 5
+ colSpan: 4
+ rowSpan: 3
+ }
+ metadata: {
+ inputs: [
+ {
+ name: 'options'
+ value: {
+ chart: {
+ metrics: [
+ {
+ resourceMetadata: {
+ id: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+ }
+ name: 'availabilityResults/availabilityPercentage'
+ aggregationType: 4
+ namespace: 'microsoft.insights/components'
+ metricVisualization: {
+ displayName: 'Availability'
+ color: '#47BDF5'
+ }
+ }
+ ]
+ title: 'Average availability'
+ visualization: {
+ chartType: 3
+ legendVisualization: {
+ isVisible: true
+ position: 2
+ hideSubtitle: false
+ }
+ axisVisualization: {
+ x: {
+ isVisible: true
+ axisType: 2
+ }
+ y: {
+ isVisible: true
+ axisType: 1
+ }
+ }
+ }
+ openBladeOnClick: {
+ openBlade: true
+ destinationBlade: {
+ extensionName: 'HubsExtension'
+ bladeName: 'ResourceMenuBlade'
+ parameters: {
+ id: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+ menuid: 'availability'
+ }
+ }
+ }
+ }
+ }
+ }
+ {
+ name: 'sharedTimeRange'
+ isOptional: true
+ }
+ ]
+ #disable-next-line BCP036
+ type: 'Extension/HubsExtension/PartType/MonitorChartPart'
+ settings: {}
+ }
+ }
+ {
+ position: {
+ x: 4
+ y: 5
+ colSpan: 4
+ rowSpan: 3
+ }
+ metadata: {
+ inputs: [
+ {
+ name: 'options'
+ value: {
+ chart: {
+ metrics: [
+ {
+ resourceMetadata: {
+ id: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+ }
+ name: 'exceptions/server'
+ aggregationType: 7
+ namespace: 'microsoft.insights/components'
+ metricVisualization: {
+ displayName: 'Server exceptions'
+ color: '#47BDF5'
+ }
+ }
+ {
+ resourceMetadata: {
+ id: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+ }
+ name: 'dependencies/failed'
+ aggregationType: 7
+ namespace: 'microsoft.insights/components'
+ metricVisualization: {
+ displayName: 'Dependency failures'
+ color: '#7E58FF'
+ }
+ }
+ ]
+ title: 'Server exceptions and Dependency failures'
+ visualization: {
+ chartType: 2
+ legendVisualization: {
+ isVisible: true
+ position: 2
+ hideSubtitle: false
+ }
+ axisVisualization: {
+ x: {
+ isVisible: true
+ axisType: 2
+ }
+ y: {
+ isVisible: true
+ axisType: 1
+ }
+ }
+ }
+ }
+ }
+ }
+ {
+ name: 'sharedTimeRange'
+ isOptional: true
+ }
+ ]
+ #disable-next-line BCP036
+ type: 'Extension/HubsExtension/PartType/MonitorChartPart'
+ settings: {}
+ }
+ }
+ {
+ position: {
+ x: 8
+ y: 5
+ colSpan: 4
+ rowSpan: 3
+ }
+ metadata: {
+ inputs: [
+ {
+ name: 'options'
+ value: {
+ chart: {
+ metrics: [
+ {
+ resourceMetadata: {
+ id: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+ }
+ name: 'performanceCounters/processorCpuPercentage'
+ aggregationType: 4
+ namespace: 'microsoft.insights/components'
+ metricVisualization: {
+ displayName: 'Processor time'
+ color: '#47BDF5'
+ }
+ }
+ {
+ resourceMetadata: {
+ id: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+ }
+ name: 'performanceCounters/processCpuPercentage'
+ aggregationType: 4
+ namespace: 'microsoft.insights/components'
+ metricVisualization: {
+ displayName: 'Process CPU'
+ color: '#7E58FF'
+ }
+ }
+ ]
+ title: 'Average processor and process CPU utilization'
+ visualization: {
+ chartType: 2
+ legendVisualization: {
+ isVisible: true
+ position: 2
+ hideSubtitle: false
+ }
+ axisVisualization: {
+ x: {
+ isVisible: true
+ axisType: 2
+ }
+ y: {
+ isVisible: true
+ axisType: 1
+ }
+ }
+ }
+ }
+ }
+ }
+ {
+ name: 'sharedTimeRange'
+ isOptional: true
+ }
+ ]
+ #disable-next-line BCP036
+ type: 'Extension/HubsExtension/PartType/MonitorChartPart'
+ settings: {}
+ }
+ }
+ {
+ position: {
+ x: 12
+ y: 5
+ colSpan: 4
+ rowSpan: 3
+ }
+ metadata: {
+ inputs: [
+ {
+ name: 'options'
+ value: {
+ chart: {
+ metrics: [
+ {
+ resourceMetadata: {
+ id: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+ }
+ name: 'exceptions/browser'
+ aggregationType: 7
+ namespace: 'microsoft.insights/components'
+ metricVisualization: {
+ displayName: 'Browser exceptions'
+ color: '#47BDF5'
+ }
+ }
+ ]
+ title: 'Browser exceptions'
+ visualization: {
+ chartType: 2
+ legendVisualization: {
+ isVisible: true
+ position: 2
+ hideSubtitle: false
+ }
+ axisVisualization: {
+ x: {
+ isVisible: true
+ axisType: 2
+ }
+ y: {
+ isVisible: true
+ axisType: 1
+ }
+ }
+ }
+ }
+ }
+ }
+ {
+ name: 'sharedTimeRange'
+ isOptional: true
+ }
+ ]
+ #disable-next-line BCP036
+ type: 'Extension/HubsExtension/PartType/MonitorChartPart'
+ settings: {}
+ }
+ }
+ {
+ position: {
+ x: 0
+ y: 8
+ colSpan: 4
+ rowSpan: 3
+ }
+ metadata: {
+ inputs: [
+ {
+ name: 'options'
+ value: {
+ chart: {
+ metrics: [
+ {
+ resourceMetadata: {
+ id: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+ }
+ name: 'availabilityResults/count'
+ aggregationType: 7
+ namespace: 'microsoft.insights/components'
+ metricVisualization: {
+ displayName: 'Availability test results count'
+ color: '#47BDF5'
+ }
+ }
+ ]
+ title: 'Availability test results count'
+ visualization: {
+ chartType: 2
+ legendVisualization: {
+ isVisible: true
+ position: 2
+ hideSubtitle: false
+ }
+ axisVisualization: {
+ x: {
+ isVisible: true
+ axisType: 2
+ }
+ y: {
+ isVisible: true
+ axisType: 1
+ }
+ }
+ }
+ }
+ }
+ }
+ {
+ name: 'sharedTimeRange'
+ isOptional: true
+ }
+ ]
+ #disable-next-line BCP036
+ type: 'Extension/HubsExtension/PartType/MonitorChartPart'
+ settings: {}
+ }
+ }
+ {
+ position: {
+ x: 4
+ y: 8
+ colSpan: 4
+ rowSpan: 3
+ }
+ metadata: {
+ inputs: [
+ {
+ name: 'options'
+ value: {
+ chart: {
+ metrics: [
+ {
+ resourceMetadata: {
+ id: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+ }
+ name: 'performanceCounters/processIOBytesPerSecond'
+ aggregationType: 4
+ namespace: 'microsoft.insights/components'
+ metricVisualization: {
+ displayName: 'Process IO rate'
+ color: '#47BDF5'
+ }
+ }
+ ]
+ title: 'Average process I/O rate'
+ visualization: {
+ chartType: 2
+ legendVisualization: {
+ isVisible: true
+ position: 2
+ hideSubtitle: false
+ }
+ axisVisualization: {
+ x: {
+ isVisible: true
+ axisType: 2
+ }
+ y: {
+ isVisible: true
+ axisType: 1
+ }
+ }
+ }
+ }
+ }
+ }
+ {
+ name: 'sharedTimeRange'
+ isOptional: true
+ }
+ ]
+ #disable-next-line BCP036
+ type: 'Extension/HubsExtension/PartType/MonitorChartPart'
+ settings: {}
+ }
+ }
+ {
+ position: {
+ x: 8
+ y: 8
+ colSpan: 4
+ rowSpan: 3
+ }
+ metadata: {
+ inputs: [
+ {
+ name: 'options'
+ value: {
+ chart: {
+ metrics: [
+ {
+ resourceMetadata: {
+ id: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+ }
+ name: 'performanceCounters/memoryAvailableBytes'
+ aggregationType: 4
+ namespace: 'microsoft.insights/components'
+ metricVisualization: {
+ displayName: 'Available memory'
+ color: '#47BDF5'
+ }
+ }
+ ]
+ title: 'Average available memory'
+ visualization: {
+ chartType: 2
+ legendVisualization: {
+ isVisible: true
+ position: 2
+ hideSubtitle: false
+ }
+ axisVisualization: {
+ x: {
+ isVisible: true
+ axisType: 2
+ }
+ y: {
+ isVisible: true
+ axisType: 1
+ }
+ }
+ }
+ }
+ }
+ }
+ {
+ name: 'sharedTimeRange'
+ isOptional: true
+ }
+ ]
+ #disable-next-line BCP036
+ type: 'Extension/HubsExtension/PartType/MonitorChartPart'
+ settings: {}
+ }
+ }
+ ]
+ }
+ ]
+ }
+}
+
+resource applicationInsights 'Microsoft.Insights/components@2020-02-02' existing = {
+ name: applicationInsightsName
+}
diff --git a/infra/core/monitor/applicationinsights.bicep b/infra/core/monitor/applicationinsights.bicep
new file mode 100644
index 0000000..4b4d01e
--- /dev/null
+++ b/infra/core/monitor/applicationinsights.bicep
@@ -0,0 +1,30 @@
+metadata description = 'Creates an Application Insights instance based on an existing Log Analytics workspace.'
+param name string
+param dashboardName string = ''
+param location string = resourceGroup().location
+param tags object = {}
+param logAnalyticsWorkspaceId string
+
+resource applicationInsights 'Microsoft.Insights/components@2020-02-02' = {
+ name: name
+ location: location
+ tags: tags
+ kind: 'web'
+ properties: {
+ Application_Type: 'web'
+ WorkspaceResourceId: logAnalyticsWorkspaceId
+ }
+}
+
+module applicationInsightsDashboard 'applicationinsights-dashboard.bicep' = if (!empty(dashboardName)) {
+ name: 'application-insights-dashboard'
+ params: {
+ name: dashboardName
+ location: location
+ applicationInsightsName: applicationInsights.name
+ }
+}
+
+output connectionString string = applicationInsights.properties.ConnectionString
+output instrumentationKey string = applicationInsights.properties.InstrumentationKey
+output name string = applicationInsights.name
diff --git a/infra/core/monitor/loganalytics.bicep b/infra/core/monitor/loganalytics.bicep
new file mode 100644
index 0000000..33f9dc2
--- /dev/null
+++ b/infra/core/monitor/loganalytics.bicep
@@ -0,0 +1,22 @@
+metadata description = 'Creates a Log Analytics workspace.'
+param name string
+param location string = resourceGroup().location
+param tags object = {}
+
+resource logAnalytics 'Microsoft.OperationalInsights/workspaces@2021-12-01-preview' = {
+ name: name
+ location: location
+ tags: tags
+ properties: any({
+ retentionInDays: 30
+ features: {
+ searchVersion: 1
+ }
+ sku: {
+ name: 'PerGB2018'
+ }
+ })
+}
+
+output id string = logAnalytics.id
+output name string = logAnalytics.name
diff --git a/infra/core/security/keyvault-access.bicep b/infra/core/security/keyvault-access.bicep
new file mode 100644
index 0000000..316775f
--- /dev/null
+++ b/infra/core/security/keyvault-access.bicep
@@ -0,0 +1,22 @@
+metadata description = 'Assigns an Azure Key Vault access policy.'
+param name string = 'add'
+
+param keyVaultName string
+param permissions object = { secrets: [ 'get', 'list' ] }
+param principalId string
+
+resource keyVaultAccessPolicies 'Microsoft.KeyVault/vaults/accessPolicies@2022-07-01' = {
+ parent: keyVault
+ name: name
+ properties: {
+ accessPolicies: [ {
+ objectId: principalId
+ tenantId: subscription().tenantId
+ permissions: permissions
+ } ]
+ }
+}
+
+resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' existing = {
+ name: keyVaultName
+}
diff --git a/infra/core/security/keyvault.bicep b/infra/core/security/keyvault.bicep
new file mode 100644
index 0000000..314a1db
--- /dev/null
+++ b/infra/core/security/keyvault.bicep
@@ -0,0 +1,26 @@
+metadata description = 'Creates an Azure Key Vault.'
+param name string
+param location string = resourceGroup().location
+param tags object = {}
+
+param principalId string = ''
+
+resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' = {
+ name: name
+ location: location
+ tags: tags
+ properties: {
+ tenantId: subscription().tenantId
+ sku: { family: 'A', name: 'standard' }
+ accessPolicies: !empty(principalId) ? [
+ {
+ objectId: principalId
+ permissions: { secrets: [ 'get', 'list' ] }
+ tenantId: subscription().tenantId
+ }
+ ] : []
+ }
+}
+
+output endpoint string = keyVault.properties.vaultUri
+output name string = keyVault.name
diff --git a/infra/core/security/role.bicep b/infra/core/security/role.bicep
new file mode 100644
index 0000000..0b30cfd
--- /dev/null
+++ b/infra/core/security/role.bicep
@@ -0,0 +1,21 @@
+metadata description = 'Creates a role assignment for a service principal.'
+param principalId string
+
+@allowed([
+ 'Device'
+ 'ForeignGroup'
+ 'Group'
+ 'ServicePrincipal'
+ 'User'
+])
+param principalType string = 'ServicePrincipal'
+param roleDefinitionId string
+
+resource role 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
+ name: guid(subscription().id, resourceGroup().id, principalId, roleDefinitionId)
+ properties: {
+ principalId: principalId
+ principalType: principalType
+ roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', roleDefinitionId)
+ }
+}
diff --git a/infra/core/storage/storage-account.bicep b/infra/core/storage/storage-account.bicep
new file mode 100644
index 0000000..4b6febb
--- /dev/null
+++ b/infra/core/storage/storage-account.bicep
@@ -0,0 +1,64 @@
+metadata description = 'Creates an Azure storage account.'
+param name string
+param location string = resourceGroup().location
+param tags object = {}
+
+@allowed([
+ 'Cool'
+ 'Hot'
+ 'Premium' ])
+param accessTier string = 'Hot'
+param allowBlobPublicAccess bool = true
+param allowCrossTenantReplication bool = true
+param allowSharedKeyAccess bool = true
+param containers array = []
+param defaultToOAuthAuthentication bool = false
+param deleteRetentionPolicy object = {}
+@allowed([ 'AzureDnsZone', 'Standard' ])
+param dnsEndpointType string = 'Standard'
+param kind string = 'StorageV2'
+param minimumTlsVersion string = 'TLS1_2'
+param supportsHttpsTrafficOnly bool = true
+param networkAcls object = {
+ bypass: 'AzureServices'
+ defaultAction: 'Allow'
+}
+@allowed([ 'Enabled', 'Disabled' ])
+param publicNetworkAccess string = 'Enabled'
+param sku object = { name: 'Standard_LRS' }
+
+resource storage 'Microsoft.Storage/storageAccounts@2022-05-01' = {
+ name: name
+ location: location
+ tags: tags
+ kind: kind
+ sku: sku
+ properties: {
+ accessTier: accessTier
+ allowBlobPublicAccess: allowBlobPublicAccess
+ allowCrossTenantReplication: allowCrossTenantReplication
+ allowSharedKeyAccess: allowSharedKeyAccess
+ defaultToOAuthAuthentication: defaultToOAuthAuthentication
+ dnsEndpointType: dnsEndpointType
+ minimumTlsVersion: minimumTlsVersion
+ networkAcls: networkAcls
+ publicNetworkAccess: publicNetworkAccess
+ supportsHttpsTrafficOnly: supportsHttpsTrafficOnly
+ }
+
+ resource blobServices 'blobServices' = if (!empty(containers)) {
+ name: 'default'
+ properties: {
+ deleteRetentionPolicy: deleteRetentionPolicy
+ }
+ resource container 'containers' = [for container in containers: {
+ name: container.name
+ properties: {
+ publicAccess: contains(container, 'publicAccess') ? container.publicAccess : 'None'
+ }
+ }]
+ }
+}
+
+output name string = storage.name
+output primaryEndpoints object = storage.properties.primaryEndpoints
diff --git a/infra/main.bicep b/infra/main.bicep
new file mode 100644
index 0000000..6284d35
--- /dev/null
+++ b/infra/main.bicep
@@ -0,0 +1,224 @@
+targetScope = 'subscription'
+
+@minLength(1)
+@maxLength(64)
+@description('Name of the the environment which is used to generate a short unique hash used in all resources.')
+param environmentName string
+
+@minLength(1)
+@description('Primary location for all resources')
+param location string
+
+// Identity
+@description('Id of the user or app to assign application roles')
+param principalId string
+
+// OpenAI
+param openAIServiceName string = ''
+param openAISkuName string = 'S0'
+param embeddingDeploymentName string = 'embeddings'
+param gptDeploymentName string = 'gpt'
+
+// Azure SQL
+@secure()
+@description('SQL Server administrator password')
+param sqlAdminPassword string
+@secure()
+@description('Application user password')
+param appUserPassword string
+param dbServiceName string = ''
+param dbName string = 'session_recommender_v2'
+
+param keyVaultName string = ''
+
+param storageAccountName string = ''
+
+param functionAppName string = ''
+
+param hostingPlanName string = ''
+param staticWebAppName string = ''
+
+param applicationInsightsName string = ''
+
+param logAnalyticsName string = ''
+
+@description('Flag to Use keyvault to store and use keys')
+param useKeyVault bool = true
+
+var abbrs = loadJsonContent('./abbreviations.json')
+var resourceToken = toLower(uniqueString(subscription().id, environmentName, location))
+var tags = { 'azd-env-name': environmentName }
+var rgName = 'rg-${environmentName}'
+
+// Organize resources in a resource group
+resource rg 'Microsoft.Resources/resourceGroups@2021-04-01' = {
+ name: rgName
+ location: location
+ tags: tags
+}
+
+module openAI 'app/openai.bicep' = {
+ name: 'openai'
+ scope: rg
+ params: {
+ name: !empty(openAIServiceName) ? openAIServiceName : '${abbrs.cognitiveServicesAccounts}${resourceToken}'
+ location: location
+ tags: tags
+ sku: {
+ name: openAISkuName
+ }
+ deployments: [
+ {
+ name: embeddingDeploymentName
+ model: {
+ format: 'OpenAI'
+ name: 'text-embedding-ada-002'
+ version: '2'
+ }
+ capacity: 30
+ }
+ {
+ name: gptDeploymentName
+ model: {
+ format: 'OpenAI'
+ name: 'gpt-35-turbo'
+ version: '0613'
+ }
+ capacity: 120
+ }
+ ]
+ keyVaultName: keyVault.outputs.name
+ useKeyVault: useKeyVault
+ }
+}
+
+module database 'app/sqlserver.bicep' = {
+ name: 'database'
+ scope: rg
+ params: {
+ tags: tags
+ location: location
+ appUserPassword: appUserPassword
+ sqlAdminPassword: sqlAdminPassword
+ databaseName: dbName
+ name: !empty(dbServiceName) ? dbServiceName : '${abbrs.sqlServers}catalog-${resourceToken}'
+ openAIEndpoint: openAI.outputs.endpoint
+ openAIServiceName: openAI.outputs.name
+ openAIDeploymentName: embeddingDeploymentName
+ principalId: principalId
+ }
+}
+
+module keyVault 'core/security/keyvault.bicep' = {
+ name: 'keyvault'
+ scope: rg
+ params: {
+ name: !empty(keyVaultName) ? keyVaultName : '${abbrs.keyVaultVaults}${resourceToken}'
+ location: location
+ tags: tags
+ principalId: principalId
+ }
+}
+
+module hostingPlan 'core/host/appserviceplan.bicep' = {
+ name: 'hostingPlan'
+ scope: rg
+ params: {
+ tags: tags
+ location: location
+ name: !empty(hostingPlanName) ? hostingPlanName : '${abbrs.webServerFarms}${resourceToken}'
+ sku: {
+ name: 'Y1'
+ tier: 'Dynamic'
+ }
+ kind: 'linux'
+ }
+}
+
+module logAnalytics 'core/monitor/loganalytics.bicep' ={
+ name: 'logAnalytics'
+ scope: rg
+ params: {
+ name: !empty(logAnalyticsName) ? logAnalyticsName : '${abbrs.insightsComponents}${resourceToken}'
+ location: location
+ }
+}
+
+module applicationInsights 'core/monitor/applicationinsights.bicep' = {
+ name: 'monitoring'
+ scope: rg
+ params: {
+ location: location
+ tags: tags
+ name: !empty(applicationInsightsName) ? applicationInsightsName : '${abbrs.insightsComponents}${resourceToken}'
+ logAnalyticsWorkspaceId: logAnalytics.outputs.id
+ }
+}
+
+module functionApp 'app/functions.bicep' = {
+ name: 'function'
+ scope: rg
+ params: {
+ tags: union(tags, { 'azd-service-name': 'functionapp' })
+ location: location
+ storageAccountName: storageAccount.outputs.name
+ openAIKeyName: useKeyVault ? openAI.outputs.openAIKeyName : ''
+ functionAppName: !empty(functionAppName) ? functionAppName : '${abbrs.webSitesFunctions}${resourceToken}'
+ hostingPlanId: hostingPlan.outputs.id
+ sqlConnectionString: '${database.outputs.connectionString}; Password=${appUserPassword}'
+ openAIEmebddingDeploymentName: embeddingDeploymentName
+ openAIGPTDeploymentName: gptDeploymentName
+ openAIEndpoint: openAI.outputs.endpoint
+ keyVaultName: keyVault.outputs.name
+ applicationInsightsConnectionString: applicationInsights.outputs.connectionString
+ useKeyVault: useKeyVault
+ openAIName: openAI.outputs.name
+ keyVaultEndpoint: keyVault.outputs.endpoint
+ }
+}
+
+module storageAccount 'core/storage/storage-account.bicep' = {
+ name: 'storage'
+ scope: rg
+ params: {
+ tags: tags
+ name: !empty(storageAccountName) ? storageAccountName : '${abbrs.storageStorageAccounts}${resourceToken}'
+ location: location
+ }
+}
+
+module funcaccess './core/security/keyvault-access.bicep' = if (useKeyVault) {
+ name: 'web-keyvault-access'
+ scope: rg
+ params: {
+ keyVaultName: keyVault.outputs.name
+ principalId: functionApp.outputs.identityPrincipalId
+ }
+}
+
+module web 'app/staticwebapp.bicep' = {
+ name: 'web'
+ scope: rg
+ params: {
+ name: !empty(staticWebAppName) ? staticWebAppName : '${abbrs.webStaticSites}${resourceToken}'
+ location: location
+ tags: union(tags, { 'azd-service-name': 'web' })
+ sqlConnectionString: '${database.outputs.connectionString}; Password=${appUserPassword}'
+ sqlServerId: database.outputs.id
+ sqlServerLocation: location
+ apiResourceId: functionApp.outputs.functionAppResourceId
+ }
+}
+
+output AZURE_SQL_SQLSERVICE_CONNECTION_STRING_KEY string = database.outputs.connectionStringKey
+output AZURE_FUNCTIONAPP_NAME string = functionApp.outputs.name
+output AZURE_FUNCTIONAPP_ID string = functionApp.outputs.functionAppResourceId
+output AZURE_KEY_VAULT_ENDPOINT string = keyVault.outputs.endpoint
+output AZURE_KEY_VALUT_NAME string = keyVault.outputs.name
+output AZURE_LOCATION string = location
+output AZURE_TENANT_ID string = tenant().tenantId
+output APPLICATIONINSIGHTS_CONNECTION_STRING string = applicationInsights.outputs.connectionString
+output AZURE_STORAGE_NAME string = storageAccount.outputs.name
+output AZURE_STATIC_WEB_URL string = web.outputs.uri
+output LOG_ANALYTICS_ID string = logAnalytics.outputs.id
+output USE_KEY_VAULT bool = useKeyVault
diff --git a/infra/main.parameters.json b/infra/main.parameters.json
new file mode 100644
index 0000000..f82b5e1
--- /dev/null
+++ b/infra/main.parameters.json
@@ -0,0 +1,24 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "location": {
+ "value": "${AZURE_LOCATION}"
+ },
+ "environmentName": {
+ "value": "${AZURE_ENV_NAME}"
+ },
+ "principalId": {
+ "value": "${AZURE_PRINCIPAL_ID}"
+ },
+ "sqlAdminPassword": {
+ "value": "$(secretOrRandomPassword ${AZURE_KEY_VAULT_NAME} sqlAdminPassword)"
+ },
+ "appUserPassword": {
+ "value": "$(secretOrRandomPassword ${AZURE_KEY_VAULT_NAME} appUserPassword)"
+ },
+ "useKeyVault": {
+ "value": "${USE_KEY_VAULT=true}"
+ }
+ }
+}
\ No newline at end of file
diff --git a/swa-cli.config.json b/swa-cli.config.json
new file mode 100644
index 0000000..aafbc9f
--- /dev/null
+++ b/swa-cli.config.json
@@ -0,0 +1,11 @@
+{
+ "$schema": "https://aka.ms/azure/static-web-apps-cli/schema",
+ "configurations": {
+ "client": {
+ "appLocation": "client",
+ "outputLocation": "dist",
+ "appBuildCommand": "npm run build",
+ "run": "npm run dev"
+ }
+ }
+}
diff --git a/swa-db-connections/staticwebapp.database.config.json b/swa-db-connections/staticwebapp.database.config.json
new file mode 100644
index 0000000..2389f09
--- /dev/null
+++ b/swa-db-connections/staticwebapp.database.config.json
@@ -0,0 +1,131 @@
+{
+ "$schema": "https://github.com/Azure/data-api-builder/releases/download/v0.9.7/dab.draft.schema.json",
+ "data-source": {
+ "database-type": "mssql",
+ "connection-string": "@env('MSSQL')",
+ "options": {
+ "set-session-context": false
+ }
+ },
+ "runtime": {
+ "rest": {
+ "enabled": true,
+ "path": "/rest",
+ "request-body-strict": true
+ },
+ "graphql": {
+ "enabled": true,
+ "path": "/graphql",
+ "allow-introspection": true
+ },
+ "host": {
+ "cors": {
+ "origins": [
+ "*"
+ ],
+ "allow-credentials": false
+ },
+ "authentication": {
+ "provider": "StaticWebApps"
+ },
+ "mode": "development"
+ }
+ },
+ "entities": {
+ "FindRelatedSessions": {
+ "source": {
+ "object": "web.find_sessions",
+ "type": "stored-procedure",
+ "parameters": {
+ "text": "",
+ "top": 10,
+ "min_similarity": 0.75
+ }
+ },
+ "graphql": {
+ "enabled": false,
+ "operation": "query"
+ },
+ "rest": {
+ "enabled": true,
+ "path": "/find",
+ "methods": [
+ "post"
+ ]
+ },
+ "permissions": [
+ {
+ "role": "anonymous",
+ "actions": [
+ {
+ "action": "execute"
+ }
+ ]
+ }
+ ]
+ },
+ "GetSessionsCount": {
+ "source": {
+ "object": "web.get_sessions_count",
+ "type": "stored-procedure"
+ },
+ "graphql": {
+ "enabled": false,
+ "operation": "query"
+ },
+ "rest": {
+ "enabled": true,
+ "path": "/sessions-count",
+ "methods": [
+ "get"
+ ]
+ },
+ "permissions": [
+ {
+ "role": "anonymous",
+ "actions": [
+ {
+ "action": "execute"
+ }
+ ]
+ }
+ ]
+ },
+ "Session": {
+ "source": {
+ "object": "web.sessions",
+ "type": "table"
+ },
+ "graphql": {
+ "enabled": true,
+ "type": {
+ "singular": "Session",
+ "plural": "Sessions"
+ }
+ },
+ "rest": {
+ "enabled": true,
+ "path": "/sessions"
+ },
+ "permissions": [
+ {
+ "role": "anonymous",
+ "actions": [
+ {
+ "action": "read"
+ }
+ ]
+ },
+ {
+ "role": "authenticated",
+ "actions": [
+ {
+ "action": "*"
+ }
+ ]
+ }
+
+ ]
+ }
+ }
+}
\ No newline at end of file