diff --git a/.devcontainer/README.md b/.devcontainer/README.md new file mode 100644 index 0000000000000000000000000000000000000000..0156438838017400c559f0485022c68f99cbcbf9 --- /dev/null +++ b/.devcontainer/README.md @@ -0,0 +1,73 @@ +# AnythingLLM Development Container Setup + +Welcome to the AnythingLLM development container configuration, designed to create a seamless and feature-rich development environment for this project. + +

PLEASE READ THIS

+ +## Prerequisites + +- [Docker](https://www.docker.com/get-started) +- [Visual Studio Code](https://code.visualstudio.com/) +- [Remote - Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) VS Code extension + +## Features + +- **Base Image**: Built on `mcr.microsoft.com/devcontainers/javascript-node:1-18-bookworm`, thus Node.JS LTS v18. +- **Additional Tools**: Includes `hadolint`, and essential apt-packages such as `curl`, `gnupg`, and more. +- **Ports**: Configured to auto-forward ports `3000` (Frontend) and `3001` (Backend). +- **Environment Variables**: Sets `NODE_ENV` to `development` and `ESLINT_USE_FLAT_CONFIG` to `true`. +- **VS Code Extensions**: A suite of extensions such as `Prettier`, `Docker`, `ESLint`, and more are automatically installed. Please revise if you do not agree with any of these extensions. AI-powered extensions and time trackers are (for now) not included to avoid any privacy concerns, but you can install them later in your own environment. + +## Getting Started + +1. Using GitHub Codespaces. Just select to create a new workspace, and the devcontainer will be created for you. + +2. Using your Local VSCode (Release or Insiders). We suggest you first make a fork of the repo and then clone it to your local machine using VSCode tools. Then open the project folder in VSCode, which will prompt you to open the project in a devcontainer. Select yes, and the devcontainer will be created for you. If this does not happen, you can open the command palette and select "Remote-Containers: Reopen in Container". + +## On Creation: + +When the container is built for the first time, it will automatically run `yarn setup` to ensure everything is in place for the Collector, Server and Frontend. This command is expected to be automatically re-run if there is a content change on next reboot. + +## Work in the Container: + +Once the container is up, be patient. Some extensions may complain because dependencies are still being installed, and in the Extensions tab, some may ask you to "Reload" the project. Don't do that yet. First, wait until all settle down for the first time. We suggest you create a new VSCode profile for this devcontainer, so any configuration and extensions you change, won't affect your default profile. + +Checklist: + +- [ ] The usual message asking you to start the Server and Frontend in different windows are now "hidden" in the building process of the devcontainer. Don't forget to do as suggested. +- [ ] Open a JavaScript file, for example "server/index.js" and check if `eslint` is working. It will complain that `'err' is defined but never used.`. This means it is working. +- [ ] Open a React File, for example, "frontend/src/main.jsx," and check if `eslint` complains about `Fast refresh only works when a file has exports. Move your component(s) to a separate file.`. Again, it means `eslint` is working. Now check at the status bar if the `Prettier` has a double checkmark :heavy_check_mark: (double). It means Prettier is working. You will see a nice extension `Formatting:`:heavy_check_mark: that can be used to disable the `Format on Save` feature temporarily. +- [ ] Check if, on the left pane, you have the NPM Scripts (this may be disabled; look at the "Explorer" tree-dots up-right). There will be scripts inside the `package.json` files. You will basically need to run the `dev:collector`, `dev:server` and the `dev:frontend` in this order. When the frontend finishes starting, a window browser will open **inside** the VSCode. Still, you can open it outside. + +:warning: **Important for all developers** :warning: + +- [ ] When you are using the `NODE_ENV=development` the server will not store the configurations you set for security reasons. Please set the proper config on file `.env.development`. The side-effect if you don't, everytime you restart the server, you will be sent to the "Onboarding" page again. + +**Note when using GitHub Codespaces** + +- [ ] When running the "Server" for the first time, it will automatically configure its port to be publicly accessible by default, as this is required for the front end to reach the server backend. To know more, read the content of the `.env` file on the frontend folder about this, and if any issues occur, make sure to manually set the port "Visibility" of the "Server" is set to "Public" if needed. Again, this is only needed for developing on GitHub Codespaces. + + +**For the Collector:** + +- [x] In the past, the Collector dwelled within the Python domain, but now it has journeyed to the splendid realm of Node.JS. Consequently, the configuration complexities of bygone versions are no longer a concern. + +### Now it is ready to start + +In the status bar you will see three shortcuts names `Collector`, `Server` and `Frontend`. Just click-and-wait on that order (don't forget to set the Server port 3001 to Public if you are using GH Codespaces **_before_** starting the Frontend). + +Now you can enjoy your time developing instead of reconfiguring everything. + +## Debugging with the devcontainers + +### For debugging the collector, server and frontend + +First, make sure the built-in extension (ms-vscode.js-debug) is active (I don't know why it would not be, but just in case). If you want, you can install the nightly version (ms-vscode.js-debug-nightly) + +Then, in the "Run and Debug" tab (Ctrl+shift+D), you can select on the menu: + +- Collector debug. This will start the collector in debug mode and attach the debugger. Works very well. +- Server debug. This will start the server in debug mode and attach the debugger. Works very well. +- Frontend debug. This will start the frontend in debug mode and attach the debugger. I am still struggling with this one. I don't know if VSCode can handle the .jsx files seamlessly as the pure .js on the server. Maybe there is a need for a particular configuration for Vite or React. Anyway, it starts. Another two configurations launch Chrome and Edge, and I think we could add breakpoints on .jsx files somehow. The best scenario would be always to use the embedded browser. WIP. + +Please leave comments on the Issues tab or the [![](https://img.shields.io/discord/1114740394715004990?logo=Discord&logoColor=white&label=Discord&labelColor=%235568ee&color=%2355A2DD&link=https%3A%2F%2Fdiscord.gg%2F6UyHPeGZAC)]("https://discord.gg/6UyHPeGZAC") diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000000000000000000000000000000000000..254ae02443fb28d6b835d3567fc2d69a160f85a6 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,211 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/javascript-node +{ + "name": "Node.js", + // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile + // "build": { + // "args": { + // "ARG_UID": "1000", + // "ARG_GID": "1000" + // }, + // "dockerfile": "Dockerfile" + // }, + // "containerUser": "anythingllm", + // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile + "image": "mcr.microsoft.com/devcontainers/javascript-node:1-18-bookworm", + // Features to add to the dev container. More info: https://containers.dev/features. + "features": { + // Docker very useful linter + "ghcr.io/dhoeric/features/hadolint:1": { + "version": "latest" + }, + // Terraform support + "ghcr.io/devcontainers/features/terraform:1": {}, + // Just a wrap to install needed packages + "ghcr.io/devcontainers-contrib/features/apt-packages:1": { + // Dependencies copied from ../docker/Dockerfile plus some dev stuff + "packages": [ + "build-essential", + "ca-certificates", + "curl", + "ffmpeg", + "fonts-liberation", + "git", + "gnupg", + "htop", + "less", + "libappindicator1", + "libasound2", + "libatk-bridge2.0-0", + "libatk1.0-0", + "libc6", + "libcairo2", + "libcups2", + "libdbus-1-3", + "libexpat1", + "libfontconfig1", + "libgbm1", + "libgcc1", + "libgfortran5", + "libglib2.0-0", + "libgtk-3-0", + "libnspr4", + "libnss3", + "libpango-1.0-0", + "libpangocairo-1.0-0", + "libstdc++6", + "libx11-6", + "libx11-xcb1", + "libxcb1", + "libxcomposite1", + "libxcursor1", + "libxdamage1", + "libxext6", + "libxfixes3", + "libxi6", + "libxrandr2", + "libxrender1", + "libxss1", + "libxtst6", + "locales", + "lsb-release", + "procps", + "tzdata", + "wget", + "xdg-utils" + ] + } + }, + "updateContentCommand": "cd server && yarn && cd ../collector && PUPPETEER_DOWNLOAD_BASE_URL=https://storage.googleapis.com/chrome-for-testing-public yarn && cd ../frontend && yarn && cd .. && yarn setup:envs && yarn prisma:setup && echo \"Please run yarn dev:server, yarn dev:collector, and yarn dev:frontend in separate terminal tabs.\"", + // Use 'postCreateCommand' to run commands after the container is created. + // This configures VITE for github codespaces and installs gh cli + "postCreateCommand": "if [ \"${CODESPACES}\" = \"true\" ]; then echo 'VITE_API_BASE=\"https://$CODESPACE_NAME-3001.$GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN/api\"' > ./frontend/.env && (type -p wget >/dev/null || (sudo apt update && sudo apt-get install wget -y)) && sudo mkdir -p -m 755 /etc/apt/keyrings && wget -qO- https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null && sudo chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg && echo \"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main\" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null && sudo apt update && sudo apt install gh -y; fi", + "portsAttributes": { + "3001": { + "label": "Backend", + "onAutoForward": "notify" + }, + "3000": { + "label": "Frontend", + "onAutoForward": "openPreview" + } + }, + "capAdd": [ + "SYS_ADMIN" // needed for puppeteer using headless chrome in sandbox + ], + "remoteEnv": { + "NODE_ENV": "development", + "ESLINT_USE_FLAT_CONFIG": "true", + "ANYTHING_LLM_RUNTIME": "docker" + }, + // "initializeCommand": "echo Initialize....", + "shutdownAction": "stopContainer", + // Configure tool-specific properties. + "customizations": { + "codespaces": { + "openFiles": [ + "README.md", + ".devcontainer/README.md" + ] + }, + "vscode": { + "openFiles": [ + "README.md", + ".devcontainer/README.md" + ], + "extensions": [ + "bierner.github-markdown-preview", + "bradlc.vscode-tailwindcss", + "dbaeumer.vscode-eslint", + "editorconfig.editorconfig", + "esbenp.prettier-vscode", + "exiasr.hadolint", + "flowtype.flow-for-vscode", + "gamunu.vscode-yarn", + "hashicorp.terraform", + "mariusschulz.yarn-lock-syntax", + "ms-azuretools.vscode-docker", + "streetsidesoftware.code-spell-checker", + "actboy168.tasks", + "tombonnike.vscode-status-bar-format-toggle", + "ms-vscode.js-debug" + ], + "settings": { + "[css]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[dockercompose]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[dockerfile]": { + "editor.defaultFormatter": "ms-azuretools.vscode-docker" + }, + "[html]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[javascript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[javascriptreact]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[json]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[jsonc]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[markdown]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[postcss]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[toml]": { + "editor.defaultFormatter": "tamasfe.even-better-toml" + }, + "eslint.debug": true, + "eslint.enable": true, + "eslint.experimental.useFlatConfig": true, + "eslint.run": "onSave", + "files.associations": { + ".*ignore": "ignore", + ".editorconfig": "editorconfig", + ".env*": "properties", + ".flowconfig": "ini", + ".prettierrc": "json", + "*.css": "tailwindcss", + "*.md": "markdown", + "*.sh": "shellscript", + "docker-compose.*": "dockercompose", + "Dockerfile*": "dockerfile", + "yarn.lock": "yarnlock" + }, + "javascript.format.enable": false, + "javascript.inlayHints.enumMemberValues.enabled": true, + "javascript.inlayHints.functionLikeReturnTypes.enabled": true, + "javascript.inlayHints.parameterTypes.enabled": true, + "javascript.inlayHints.variableTypes.enabled": true, + "js/ts.implicitProjectConfig.module": "CommonJS", + "json.format.enable": false, + "json.schemaDownload.enable": true, + "npm.autoDetect": "on", + "npm.packageManager": "yarn", + "prettier.useEditorConfig": false, + "tailwindCSS.files.exclude": [ + "**/.git/**", + "**/node_modules/**", + "**/.hg/**", + "**/.svn/**", + "**/dist/**" + ], + "typescript.validate.enable": false, + "workbench.editorAssociations": { + "*.md": "vscode.markdown.preview.editor" + } + } + } + } + // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. + // "remoteUser": "root" +} diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000000000000000000000000000000000..e175db54f3af2a39a8396efd351dfdafd760f529 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,17 @@ +# EditorConfig is awesome: https://EditorConfig.org + +# top-most EditorConfig file +root = true + +[*] +# Non-configurable Prettier behaviors +charset = utf-8 +insert_final_newline = true +trim_trailing_whitespace = true + +# Configurable Prettier behaviors +# (change these if your Prettier config differs) +end_of_line = lf +indent_style = space +indent_size = 2 +max_line_length = 80 diff --git a/.gitattributes b/.gitattributes index a6344aac8c09253b3b630fb776ae94478aa0275b..4eb4f0bda4c659654c74c68c7f81fef6809bcaa9 100644 --- a/.gitattributes +++ b/.gitattributes @@ -33,3 +33,6 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text *.zip filter=lfs diff=lfs merge=lfs -text *.zst filter=lfs diff=lfs merge=lfs -text *tfevents* filter=lfs diff=lfs merge=lfs -text +*.ttf filter=lfs diff=lfs merge=lfs -text +*.png filter=lfs diff=lfs merge=lfs -text +*.webm filter=lfs diff=lfs merge=lfs -text diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000000000000000000000000000000000000..411f850fd356987108e75b321231332df9704bd2 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: Mintplex-Labs \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/01_bug.yml b/.github/ISSUE_TEMPLATE/01_bug.yml new file mode 100644 index 0000000000000000000000000000000000000000..582670a0881d06864cf444d4684d396771e0d567 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/01_bug.yml @@ -0,0 +1,42 @@ +name: 🐛 Bug Report +description: File a bug report for AnythingLLM +title: "[BUG]: " +labels: [possible bug] +body: + - type: markdown + attributes: + value: | + Use this template to file a bug report for AnythingLLM. Please be as descriptive as possible to allow everyone to replicate and solve your issue. + - type: dropdown + id: runtime + attributes: + label: How are you running AnythingLLM? + description: AnythingLLM can be run in many environments, pick the one that best represents where you encounter the bug. + options: + - Docker (local) + - Docker (remote machine) + - Local development + - AnythingLLM desktop app + - All versions + - Not listed + default: 0 + validations: + required: true + + - type: textarea + id: what-happened + attributes: + label: What happened? + description: Also tell us, what did you expect to happen? + validations: + required: true + + - type: textarea + id: reproduction + attributes: + label: Are there known steps to reproduce? + description: | + Let us know how to reproduce the bug and we may be able to fix it more + quickly. This is not required, but it is helpful. + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/02_feature.yml b/.github/ISSUE_TEMPLATE/02_feature.yml new file mode 100644 index 0000000000000000000000000000000000000000..89238b59f5453e8ce444882d833e2650ce32c2e4 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/02_feature.yml @@ -0,0 +1,19 @@ +name: ✨ New Feature suggestion +description: Suggest a new feature for AnythingLLM! +title: "[FEAT]: " +labels: [enhancement, feature request] +body: + - type: markdown + attributes: + value: | + Share a new idea for a feature or improvement. Be sure to search existing + issues first to avoid duplicates. + + - type: textarea + id: description + attributes: + label: What would you like to see? + description: | + Describe the feature and why it would be useful to your use-case as well as others. + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/03_documentation.yml b/.github/ISSUE_TEMPLATE/03_documentation.yml new file mode 100644 index 0000000000000000000000000000000000000000..55800856c313cfd2b958912a3e3f62d544bbf983 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/03_documentation.yml @@ -0,0 +1,13 @@ +name: 📚 Documentation improvement +title: "[DOCS]: " +description: Report an issue or problem with the documentation. +labels: [documentation] + +body: + - type: textarea + id: description + attributes: + label: Description + description: Describe the issue with the documentation that is giving you trouble or causing confusion. + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000000000000000000000000000000000000..d5485e65d88dfa9b2b5efb9b464f6c309bbcdc74 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: true +contact_links: + - name: 🧑‍🤝‍🧑 Community Discord + url: https://discord.gg/6UyHPeGZAC + about: Interact with the Mintplex Labs community here by asking for help, discussing and more! diff --git a/.github/workflows/build-and-push-image-semver.yaml b/.github/workflows/build-and-push-image-semver.yaml new file mode 100644 index 0000000000000000000000000000000000000000..1da1dda9df3f93f752561ce20153c800324729bf --- /dev/null +++ b/.github/workflows/build-and-push-image-semver.yaml @@ -0,0 +1,117 @@ +name: Publish AnythingLLM Docker image on Release (amd64 & arm64) + +concurrency: + group: build-${{ github.ref }} + cancel-in-progress: true + +on: + release: + types: [published] + +jobs: + push_multi_platform_to_registries: + name: Push Docker multi-platform image to multiple registries + runs-on: ubuntu-latest + permissions: + packages: write + contents: read + steps: + - name: Check out the repo + uses: actions/checkout@v4 + + - name: Check if DockerHub build needed + shell: bash + run: | + # Check if the secret for USERNAME is set (don't even check for the password) + if [[ -z "${{ secrets.DOCKER_USERNAME }}" ]]; then + echo "DockerHub build not needed" + echo "enabled=false" >> $GITHUB_OUTPUT + else + echo "DockerHub build needed" + echo "enabled=true" >> $GITHUB_OUTPUT + fi + id: dockerhub + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + with: + version: v0.22.0 + + - name: Log in to Docker Hub + uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a + # Only login to the Docker Hub if the repo is mintplex/anythingllm, to allow for forks to build on GHCR + if: steps.dockerhub.outputs.enabled == 'true' + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Log in to the Container registry + uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 + with: + images: | + ${{ steps.dockerhub.outputs.enabled == 'true' && 'mintplexlabs/anythingllm' || '' }} + ghcr.io/${{ github.repository }} + tags: | + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + + - name: Build and push multi-platform Docker image + uses: docker/build-push-action@v6 + with: + context: . + file: ./docker/Dockerfile + push: true + sbom: true + provenance: mode=max + platforms: linux/amd64,linux/arm64 + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + + # For Docker scout there are some intermediary reported CVEs which exists outside + # of execution content or are unreachable by an attacker but exist in image. + # We create VEX files for these so they don't show in scout summary. + - name: Collect known and verified CVE exceptions + id: cve-list + run: | + # Collect CVEs from filenames in vex folder + CVE_NAMES="" + for file in ./docker/vex/*.vex.json; do + [ -e "$file" ] || continue + filename=$(basename "$file") + stripped_filename=${filename%.vex.json} + CVE_NAMES+=" $stripped_filename" + done + echo "CVE_EXCEPTIONS=$CVE_NAMES" >> $GITHUB_OUTPUT + shell: bash + + # About VEX attestations https://docs.docker.com/scout/explore/exceptions/ + # Justifications https://github.com/openvex/spec/blob/main/OPENVEX-SPEC.md#status-justifications + - name: Add VEX attestations + env: + CVE_EXCEPTIONS: ${{ steps.cve-list.outputs.CVE_EXCEPTIONS }} + run: | + echo $CVE_EXCEPTIONS + curl -sSfL https://raw.githubusercontent.com/docker/scout-cli/main/install.sh | sh -s -- + for cve in $CVE_EXCEPTIONS; do + for tag in "${{ join(fromJSON(steps.meta.outputs.json).tags, ' ') }}"; do + echo "Attaching VEX exception $cve to $tag" + docker scout attestation add \ + --file "./docker/vex/$cve.vex.json" \ + --predicate-type https://openvex.dev/ns/v0.2.0 \ + $tag + done + done + shell: bash diff --git a/.github/workflows/build-and-push-image.yaml b/.github/workflows/build-and-push-image.yaml new file mode 100644 index 0000000000000000000000000000000000000000..2519d1362d903545a4c0aa5a5b69311bb09221e4 --- /dev/null +++ b/.github/workflows/build-and-push-image.yaml @@ -0,0 +1,138 @@ +# This GitHub action is for publishing of the primary image for AnythingLLM +# It will publish a linux/amd64 and linux/arm64 image at the same time +# This file should ONLY BY USED FOR `master` BRANCH. +# TODO: GitHub now has an ubuntu-24.04-arm64 runner, but we still need +# to use QEMU to build the arm64 image because Chromium is not available for Linux arm64 +# so builds will still fail, or fail much more often. Its inconsistent and frustrating. +name: Publish AnythingLLM Primary Docker image (amd64/arm64) + +concurrency: + group: build-${{ github.ref }} + cancel-in-progress: true + +on: + push: + branches: ['master'] # master branch only. Do not modify. + paths-ignore: + - '**.md' + - '.gitmodules' + - 'cloud-deployments/**/*' + - 'images/**/*' + - '.vscode/**/*' + - '**/.env.example' + - '.github/ISSUE_TEMPLATE/**/*' + - '.devcontainer/**/*' + - 'embed/**/*' # Embed is submodule + - 'browser-extension/**/*' # Chrome extension is submodule + - 'server/utils/agents/aibitat/example/**/*' # Do not push new image for local dev testing of new aibitat images. + - 'extras/**/*' # Extra is just for news and other local content. + +jobs: + push_multi_platform_to_registries: + name: Push Docker multi-platform image to multiple registries + runs-on: ubuntu-latest + permissions: + packages: write + contents: read + steps: + - name: Check out the repo + uses: actions/checkout@v4 + + - name: Check if DockerHub build needed + shell: bash + run: | + # Check if the secret for USERNAME is set (don't even check for the password) + if [[ -z "${{ secrets.DOCKER_USERNAME }}" ]]; then + echo "DockerHub build not needed" + echo "enabled=false" >> $GITHUB_OUTPUT + else + echo "DockerHub build needed" + echo "enabled=true" >> $GITHUB_OUTPUT + fi + id: dockerhub + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + with: + version: v0.22.0 + + - name: Log in to Docker Hub + uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a + # Only login to the Docker Hub if the repo is mintplex/anythingllm, to allow for forks to build on GHCR + if: steps.dockerhub.outputs.enabled == 'true' + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Log in to the Container registry + uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 + with: + images: | + ${{ steps.dockerhub.outputs.enabled == 'true' && 'mintplexlabs/anythingllm' || '' }} + ghcr.io/${{ github.repository }} + tags: | + type=raw,value=latest,enable={{is_default_branch}} + type=ref,event=branch + type=ref,event=tag + type=ref,event=pr + + - name: Build and push multi-platform Docker image + uses: docker/build-push-action@v6 + with: + context: . + file: ./docker/Dockerfile + push: true + sbom: true + provenance: mode=max + platforms: linux/amd64,linux/arm64 + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + + # For Docker scout there are some intermediary reported CVEs which exists outside + # of execution content or are unreachable by an attacker but exist in image. + # We create VEX files for these so they don't show in scout summary. + - name: Collect known and verified CVE exceptions + id: cve-list + run: | + # Collect CVEs from filenames in vex folder + CVE_NAMES="" + for file in ./docker/vex/*.vex.json; do + [ -e "$file" ] || continue + filename=$(basename "$file") + stripped_filename=${filename%.vex.json} + CVE_NAMES+=" $stripped_filename" + done + echo "CVE_EXCEPTIONS=$CVE_NAMES" >> $GITHUB_OUTPUT + shell: bash + + # About VEX attestations https://docs.docker.com/scout/explore/exceptions/ + # Justifications https://github.com/openvex/spec/blob/main/OPENVEX-SPEC.md#status-justifications + - name: Add VEX attestations + env: + CVE_EXCEPTIONS: ${{ steps.cve-list.outputs.CVE_EXCEPTIONS }} + run: | + echo $CVE_EXCEPTIONS + curl -sSfL https://raw.githubusercontent.com/docker/scout-cli/main/install.sh | sh -s -- + for cve in $CVE_EXCEPTIONS; do + for tag in "${{ join(fromJSON(steps.meta.outputs.json).tags, ' ') }}"; do + echo "Attaching VEX exception $cve to $tag" + docker scout attestation add \ + --file "./docker/vex/$cve.vex.json" \ + --predicate-type https://openvex.dev/ns/v0.2.0 \ + $tag + done + done + shell: bash \ No newline at end of file diff --git a/.github/workflows/check-package-versions.yaml b/.github/workflows/check-package-versions.yaml new file mode 100644 index 0000000000000000000000000000000000000000..a7435824d562bd496fb86a59fc1007b663d8a2f8 --- /dev/null +++ b/.github/workflows/check-package-versions.yaml @@ -0,0 +1,37 @@ +# This GitHub action is for checking the versions of the packages in the project. +# Any package that is present in both the `server` and `collector` package.json file +# is checked to ensure that they are the same version. +name: Check package versions + +concurrency: + group: build-${{ github.ref }} + cancel-in-progress: true + +on: + pull_request: + types: [opened, synchronize, reopened] + paths: + - "server/package.json" + - "collector/package.json" + +jobs: + run-script: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + node-version: '18' + + - name: Run verifyPackageVersions.mjs script + run: | + cd extras/scripts + node verifyPackageVersions.mjs + + - name: Fail job on error + if: failure() + run: exit 1 diff --git a/.github/workflows/check-translations.yaml b/.github/workflows/check-translations.yaml new file mode 100644 index 0000000000000000000000000000000000000000..ad1de0c2a0b90e17c4a1cd39797caae1cf167d63 --- /dev/null +++ b/.github/workflows/check-translations.yaml @@ -0,0 +1,37 @@ +# This GitHub action is for validation of all languages which translations are offered for +# in the locales folder in `frontend/src`. All languages are compared to the EN translation +# schema since that is the fallback language setting. This workflow will run on all PRs that +# modify any files in the translation directory +name: Verify translations files + +concurrency: + group: build-${{ github.ref }} + cancel-in-progress: true + +on: + pull_request: + types: [opened, synchronize, reopened] + paths: + - "frontend/src/locales/**.js" + +jobs: + run-script: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + node-version: '18' + + - name: Run verifyTranslations.mjs script + run: | + cd frontend/src/locales + node verifyTranslations.mjs + + - name: Fail job on error + if: failure() + run: exit 1 diff --git a/.github/workflows/dev-build.yaml b/.github/workflows/dev-build.yaml new file mode 100644 index 0000000000000000000000000000000000000000..583eeff7a5b0c4e7a168836524950146724b40c7 --- /dev/null +++ b/.github/workflows/dev-build.yaml @@ -0,0 +1,124 @@ +name: AnythingLLM Development Docker image (amd64) + +concurrency: + group: build-${{ github.ref }} + cancel-in-progress: true + +on: + push: + branches: ['3999-chromium-flags'] # put your current branch to create a build. Core team only. + paths-ignore: + - '**.md' + - 'cloud-deployments/*' + - 'images/**/*' + - '.vscode/**/*' + - '**/.env.example' + - '.github/ISSUE_TEMPLATE/**/*' + - '.devcontainer/**/*' + - 'embed/**/*' # Embed should be published to frontend (yarn build:publish) if any changes are introduced + - 'browser-extension/**/*' # Chrome extension is submodule + - 'server/utils/agents/aibitat/example/**/*' # Do not push new image for local dev testing of new aibitat images. + - 'extras/**/*' # Extra is just for news and other local content. + +jobs: + push_multi_platform_to_registries: + name: Push Docker multi-platform image to multiple registries + runs-on: ubuntu-latest + permissions: + packages: write + contents: read + steps: + - name: Check out the repo + uses: actions/checkout@v4 + + - name: Check if DockerHub build needed + shell: bash + run: | + # Check if the secret for USERNAME is set (don't even check for the password) + if [[ -z "${{ secrets.DOCKER_USERNAME }}" ]]; then + echo "DockerHub build not needed" + echo "enabled=false" >> $GITHUB_OUTPUT + else + echo "DockerHub build needed" + echo "enabled=true" >> $GITHUB_OUTPUT + fi + id: dockerhub + + # Uncomment this + add linux/arm64 to platforms if you want to build for arm64 as well + # - name: Set up QEMU + # uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + with: + version: v0.22.0 + + - name: Log in to Docker Hub + uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a + # Only login to the Docker Hub if the repo is mintplex/anythingllm, to allow for forks to build on GHCR + if: steps.dockerhub.outputs.enabled == 'true' + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 + with: + images: | + ${{ steps.dockerhub.outputs.enabled == 'true' && 'mintplexlabs/anythingllm' || '' }} + tags: | + type=raw,value=dev + + - name: Build and push multi-platform Docker image + uses: docker/build-push-action@v6 + with: + context: . + file: ./docker/Dockerfile + push: true + sbom: true + provenance: mode=max + platforms: linux/amd64 + # platforms: linux/amd64,linux/arm64 + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + + # For Docker scout there are some intermediary reported CVEs which exists outside + # of execution content or are unreachable by an attacker but exist in image. + # We create VEX files for these so they don't show in scout summary. + - name: Collect known and verified CVE exceptions + id: cve-list + run: | + # Collect CVEs from filenames in vex folder + CVE_NAMES="" + for file in ./docker/vex/*.vex.json; do + [ -e "$file" ] || continue + filename=$(basename "$file") + stripped_filename=${filename%.vex.json} + CVE_NAMES+=" $stripped_filename" + done + echo "CVE_EXCEPTIONS=$CVE_NAMES" >> $GITHUB_OUTPUT + shell: bash + + # About VEX attestations https://docs.docker.com/scout/explore/exceptions/ + # Justifications https://github.com/openvex/spec/blob/main/OPENVEX-SPEC.md#status-justifications + # Fixed to use v1.15.1 of scout-cli as v1.16.0 install script is broken + # https://github.com/docker/scout-cli + - name: Add VEX attestations + env: + CVE_EXCEPTIONS: ${{ steps.cve-list.outputs.CVE_EXCEPTIONS }} + run: | + echo $CVE_EXCEPTIONS + curl -sSfL https://raw.githubusercontent.com/docker/scout-cli/main/install.sh | sh -s -- + for cve in $CVE_EXCEPTIONS; do + for tag in "${{ join(fromJSON(steps.meta.outputs.json).tags, ' ') }}"; do + echo "Attaching VEX exception $cve to $tag" + docker scout attestation add \ + --file "./docker/vex/$cve.vex.json" \ + --predicate-type https://openvex.dev/ns/v0.2.0 \ + $tag + done + done + shell: bash \ No newline at end of file diff --git a/.github/workflows/run-tests.yaml b/.github/workflows/run-tests.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d303809d590e74c43a7314f03b9e65b093888a1d --- /dev/null +++ b/.github/workflows/run-tests.yaml @@ -0,0 +1,77 @@ +name: Run backend tests + +concurrency: + group: build-${{ github.ref }} + cancel-in-progress: true + +on: + pull_request: + types: [opened, synchronize, reopened] + paths: + - "server/**.js" + - "collector/**.js" + +jobs: + run-script: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + node-version: '18' + + - name: Cache root dependencies + uses: actions/cache@v3 + with: + path: | + node_modules + ~/.cache/yarn + key: ${{ runner.os }}-yarn-root-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn-root- + + - name: Cache server dependencies + uses: actions/cache@v3 + with: + path: | + server/node_modules + ~/.cache/yarn + key: ${{ runner.os }}-yarn-server-${{ hashFiles('server/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn-server- + + - name: Cache collector dependencies + uses: actions/cache@v3 + with: + path: | + collector/node_modules + ~/.cache/yarn + key: ${{ runner.os }}-yarn-collector-${{ hashFiles('collector/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn-collector- + + - name: Install root dependencies + if: steps.cache-root.outputs.cache-hit != 'true' + run: yarn install --frozen-lockfile + + - name: Install server dependencies + if: steps.cache-server.outputs.cache-hit != 'true' + run: cd server && yarn install --frozen-lockfile + + - name: Install collector dependencies + if: steps.cache-collector.outputs.cache-hit != 'true' + run: cd collector && yarn install --frozen-lockfile + + - name: Setup environment and Prisma + run: yarn setup:envs && yarn prisma:setup + + - name: Run test suites + run: yarn test + + - name: Fail job on error + if: failure() + run: exit 1 diff --git a/.github/workflows/sponsors.yaml b/.github/workflows/sponsors.yaml new file mode 100644 index 0000000000000000000000000000000000000000..925b845cc811b8b848d94244b5cc00b9c4c4838a --- /dev/null +++ b/.github/workflows/sponsors.yaml @@ -0,0 +1,44 @@ +name: Generate Sponsors README + +on: + schedule: + - cron: "0 12 * * 3" # Run every Wednesday at 12:00 PM UTC + +permissions: + contents: write +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - name: Checkout 🛎️ + uses: actions/checkout@v2 + + - name: Generate All Sponsors README + id: generate-all-sponsors + uses: JamesIves/github-sponsors-readme-action@v1 + with: + token: ${{ secrets.SPONSOR_PAT }} + file: 'README.md' + organization: true + active-only: false + marker: 'all-sponsors' + + - name: Commit and Push 🚀 + uses: stefanzweifel/git-auto-commit-action@v5 + id: auto-commit-action + with: + commit_message: 'Update Sponsors README' + file_pattern: 'README.md' + + - name: Generate PR if changes detected + uses: peter-evans/create-pull-request@v7 + if: steps.auto-commit-action.outputs.files_changed == 'true' + with: + token: ${{ secrets.GITHUB_TOKEN }} + title: 'Update Sponsors README' + branch: 'chore/update-sponsors' + base: 'master' + draft: false + reviewers: 'timothycarambat' + assignees: 'timothycarambat' + maintainer-can-modify: true \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..f4e441932060b7c9d602d08dd7400b845ac4c7c4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +v-env +.env +!.env.example + +node_modules +__pycache__ +v-env +.DS_Store +aws_cf_deploy_anything_llm.json +yarn.lock +*.bak +.idea diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000000000000000000000000000000000..0a491b4204cf7eb261e8212270b271fabdf5db53 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,7 @@ +[submodule "browser-extension"] + path = browser-extension + url = https://github.com/Mintplex-Labs/anythingllm-extension.git +[submodule "embed"] + path = embed + url = https://github.com/Mintplex-Labs/anythingllm-embed.git + branch = main diff --git a/.hadolint.yaml b/.hadolint.yaml new file mode 100644 index 0000000000000000000000000000000000000000..b76a5107288288a6d6300380d8558b50bcaea578 --- /dev/null +++ b/.hadolint.yaml @@ -0,0 +1,8 @@ +failure-threshold: warning +ignored: + - DL3008 + - DL3013 +format: tty +trustedRegistries: + - docker.io + - gcr.io diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000000000000000000000000000000000000..6aab9b43fa34ec7383f27657aea4be23b16edc9e --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +v18.18.0 diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000000000000000000000000000000000000..1c4725e585b8b431899add40babe8ba0ad91b5b6 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,17 @@ +# defaults +**/.git +**/.svn +**/.hg +**/node_modules + +#frontend +frontend/bundleinspector.html +**/dist + +#server +server/swagger/openapi.json +server/**/*.mjs + +#embed +**/static/** +embed/src/utils/chat/hljs.js diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000000000000000000000000000000000000..5e2bccfe49211f9d5fdd5f5dc5dba96267206d51 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,38 @@ +{ + "tabWidth": 2, + "useTabs": false, + "endOfLine": "lf", + "semi": true, + "singleQuote": false, + "printWidth": 80, + "trailingComma": "es5", + "bracketSpacing": true, + "bracketSameLine": false, + "overrides": [ + { + "files": ["*.js", "*.mjs", "*.jsx"], + "options": { + "parser": "flow", + "arrowParens": "always" + } + }, + { + "files": ["*.config.js"], + "options": { + "semi": false, + "parser": "flow", + "trailingComma": "none" + } + }, + { + "files": "*.html", + "options": { + "bracketSameLine": true + } + }, + { + "files": ".prettierrc", + "options": { "parser": "json" } + } + ] +} diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000000000000000000000000000000000000..911b0a7652d434a78335d3dcff3ef0a6dd17d327 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,74 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Collector debug", + "request": "launch", + "cwd": "${workspaceFolder}/collector", + "env": { + "NODE_ENV": "development" + }, + "runtimeArgs": [ + "index.js" + ], + // not using yarn/nodemon because it doesn't work with breakpoints + // "runtimeExecutable": "yarn", + "skipFiles": [ + "/**" + ], + "type": "node" + }, + { + "name": "Server debug", + "request": "launch", + "cwd": "${workspaceFolder}/server", + "env": { + "NODE_ENV": "development" + }, + "runtimeArgs": [ + "index.js" + ], + // not using yarn/nodemon because it doesn't work with breakpoints + // "runtimeExecutable": "yarn", + "skipFiles": [ + "/**" + ], + "type": "node" + }, + { + "name": "Frontend debug", + "request": "launch", + "cwd": "${workspaceFolder}/frontend", + "env": { + "NODE_ENV": "development", + }, + "runtimeExecutable": "${workspaceFolder}/frontend/node_modules/.bin/vite", + "runtimeArgs": [ + "--debug", + "--host=0.0.0.0" + ], + // "runtimeExecutable": "yarn", + "skipFiles": [ + "/**" + ], + "type": "node" + }, + { + "name": "Launch Edge", + "request": "launch", + "type": "msedge", + "url": "http://localhost:3000", + "webRoot": "${workspaceFolder}" + }, + { + "type": "chrome", + "request": "launch", + "name": "Launch Chrome against localhost", + "url": "http://localhost:3000", + "webRoot": "${workspaceFolder}" + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000000000000000000000000000000000000..e6b76c9e9dede8ce421610531a4336611bb41fc7 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,63 @@ +{ + "cSpell.words": [ + "adoc", + "aibitat", + "AIbitat", + "allm", + "anythingllm", + "Apipie", + "Astra", + "Chartable", + "cleancss", + "comkey", + "cooldown", + "cooldowns", + "datafile", + "Deduplicator", + "Dockerized", + "docpath", + "elevenlabs", + "Embeddable", + "epub", + "fireworksai", + "GROQ", + "hljs", + "huggingface", + "inferencing", + "koboldcpp", + "Langchain", + "lmstudio", + "localai", + "mbox", + "Milvus", + "Mintplex", + "mixtral", + "moderations", + "novita", + "numpages", + "Ollama", + "Oobabooga", + "openai", + "opendocument", + "openrouter", + "pagerender", + "ppio", + "Qdrant", + "royalblue", + "SearchApi", + "searxng", + "Serper", + "Serply", + "streamable", + "textgenwebui", + "togetherai", + "Unembed", + "uuidv", + "vectordbs", + "Weaviate", + "XAILLM", + "Zilliz" + ], + "eslint.experimental.useFlatConfig": true, + "docker.languageserver.formatter.ignoreMultilineInstructions": true +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000000000000000000000000000000000000..6783e17e9232adba661dae54be5f36ed91cb5719 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,94 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "type": "shell", + "options": { + "cwd": "${workspaceFolder}/collector", + "statusbar": { + "color": "#ffea00", + "detail": "Runs the collector", + "label": "Collector: $(play) run", + "running": { + "color": "#ffea00", + "label": "Collector: $(gear~spin) running" + } + } + }, + "command": "cd ${workspaceFolder}/collector/ && yarn dev", + "runOptions": { + "instanceLimit": 1, + "reevaluateOnRerun": true + }, + "presentation": { + "echo": true, + "reveal": "always", + "focus": false, + "panel": "shared", + "showReuseMessage": true, + "clear": false + }, + "label": "Collector: run" + }, + { + "type": "shell", + "options": { + "cwd": "${workspaceFolder}/server", + "statusbar": { + "color": "#ffea00", + "detail": "Runs the server", + "label": "Server: $(play) run", + "running": { + "color": "#ffea00", + "label": "Server: $(gear~spin) running" + } + } + }, + "command": "if [ \"${CODESPACES}\" = \"true\" ]; then while ! gh codespace ports -c $CODESPACE_NAME | grep 3001; do sleep 1; done; gh codespace ports visibility 3001:public -c $CODESPACE_NAME; fi & cd ${workspaceFolder}/server/ && yarn dev", + "runOptions": { + "instanceLimit": 1, + "reevaluateOnRerun": true + }, + "presentation": { + "echo": true, + "reveal": "always", + "focus": false, + "panel": "shared", + "showReuseMessage": true, + "clear": false + }, + "label": "Server: run" + }, + { + "type": "shell", + "options": { + "cwd": "${workspaceFolder}/frontend", + "statusbar": { + "color": "#ffea00", + "detail": "Runs the frontend", + "label": "Frontend: $(play) run", + "running": { + "color": "#ffea00", + "label": "Frontend: $(gear~spin) running" + } + } + }, + "command": "cd ${workspaceFolder}/frontend/ && yarn dev", + "runOptions": { + "instanceLimit": 1, + "reevaluateOnRerun": true + }, + "presentation": { + "echo": true, + "reveal": "always", + "focus": false, + "panel": "shared", + "showReuseMessage": true, + "clear": false + }, + "label": "Frontend: run" + } + ] +} diff --git a/BARE_METAL.md b/BARE_METAL.md new file mode 100644 index 0000000000000000000000000000000000000000..38b947bba6269ba3a10ae26131c1bc8e105e6da1 --- /dev/null +++ b/BARE_METAL.md @@ -0,0 +1,147 @@ +# Run AnythingLLM in production without Docker + +> [!WARNING] +> This method of deployment is **not supported** by the core-team and is to be used as a reference for your deployment. +> You are fully responsible for securing your deployment and data in this mode. +> **Any issues** experienced from bare-metal or non-containerized deployments will be **not** answered or supported. + +Here you can find the scripts and known working process to run AnythingLLM outside of a Docker container. + +### Minimum Requirements +> [!TIP] +> You should aim for at least 2GB of RAM. Disk storage is proportional to however much data +> you will be storing (documents, vectors, models, etc). Minimum 10GB recommended. + +- NodeJS v18 +- Yarn + + +## Getting started + +1. Clone the repo into your server as the user who the application will run as. +`git clone git@github.com:Mintplex-Labs/anything-llm.git` + +2. `cd anything-llm` and run `yarn setup`. This will install all dependencies to run in production as well as debug the application. + +3. `cp server/.env.example server/.env` to create the basic ENV file for where instance settings will be read from on service start. + +4. Ensure that the `server/.env` file has _at least_ these keys to start. These values will persist and this file will be automatically written and managed after your first successful boot. +``` +STORAGE_DIR="/your/absolute/path/to/server/storage" +``` + +5. Edit the `frontend/.env` file for the `VITE_BASE_API` to now be set to `/api`. This is documented in the .env for which one you should use. +``` +# VITE_API_BASE='http://localhost:3001/api' # Use this URL when developing locally +# VITE_API_BASE="https://$CODESPACE_NAME-3001.$GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN/api" # for GitHub Codespaces +VITE_API_BASE='/api' # Use this URL deploying on non-localhost address OR in docker. +``` + +## To start the application + +AnythingLLM is comprised of three main sections. The `frontend`, `server`, and `collector`. When running in production you will be running `server` and `collector` on two different processes, with a build step for compilation of the frontend. + +1. Build the frontend application. +`cd frontend && yarn build` - this will produce a `frontend/dist` folder that will be used later. + +2. Copy `frontend/dist` to `server/public` - `cp -R frontend/dist server/public`. +This should create a folder in `server` named `public` which contains a top level `index.html` file and various other files/folders. + +3. Migrate and prepare your database file. +``` +cd server && npx prisma generate --schema=./prisma/schema.prisma +cd server && npx prisma migrate deploy --schema=./prisma/schema.prisma +``` + +4. Boot the server in production +`cd server && NODE_ENV=production node index.js &` + +5. Boot the collection in another process +`cd collector && NODE_ENV=production node index.js &` + +AnythingLLM should now be running on `http://localhost:3001`! + +## Updating AnythingLLM + +To update AnythingLLM with future updates you can `git pull origin master` to pull in the latest code and then repeat steps 2 - 5 to deploy with all changes fully. + +_note_ You should ensure that each folder runs `yarn` again to ensure packages are up to date in case any dependencies were added, changed, or removed. + +_note_ You should `pkill node` before running an update so that you are not running multiple AnythingLLM processes on the same instance as this can cause conflicts. + + +### Example update script + +```shell +#!/bin/bash + +cd $HOME/anything-llm &&\ +git checkout . &&\ +git pull origin master &&\ +echo "HEAD pulled to commit $(git log -1 --pretty=format:"%h" | tail -n 1)" + +echo "Freezing current ENVs" +curl -I "http://localhost:3001/api/env-dump" | head -n 1|cut -d$' ' -f2 + +echo "Rebuilding Frontend" +cd $HOME/anything-llm/frontend && yarn && yarn build && cd $HOME/anything-llm + +echo "Copying to Server Public" +rm -rf server/public +cp -r frontend/dist server/public + +echo "Killing node processes" +pkill node + +echo "Installing collector dependencies" +cd $HOME/anything-llm/collector && yarn + +echo "Installing server dependencies & running migrations" +cd $HOME/anything-llm/server && yarn +cd $HOME/anything-llm/server && npx prisma migrate deploy --schema=./prisma/schema.prisma +cd $HOME/anything-llm/server && npx prisma generate + +echo "Booting up services." +truncate -s 0 /logs/server.log # Or any other log file location. +truncate -s 0 /logs/collector.log + +cd $HOME/anything-llm/server +(NODE_ENV=production node index.js) &> /logs/server.log & + +cd $HOME/anything-llm/collector +(NODE_ENV=production node index.js) &> /logs/collector.log & +``` + +## Using Nginx? + +If you are using Nginx, you can use the following example configuration to proxy the requests to the server. Chats for streaming require **websocket** connections, so you need to ensure that the Nginx configuration is set up to support websockets. You can do this with a simple reverse proxy configuration. + +```nginx +server { + # Enable websocket connections for agent protocol. + location ~* ^/api/agent-invocation/(.*) { + proxy_pass http://0.0.0.0:3001; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + } + + listen 80; + server_name [insert FQDN here]; + location / { + # Prevent timeouts on long-running requests. + proxy_connect_timeout 605; + proxy_send_timeout 605; + proxy_read_timeout 605; + send_timeout 605; + keepalive_timeout 605; + + # Enable readable HTTP Streaming for LLM streamed responses + proxy_buffering off; + proxy_cache off; + + # Proxy your locally running service + proxy_pass http://0.0.0.0:3001; + } +} +``` \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000000000000000000000000000000000..709746e7226dd1652d87d3b570e0bab83f9d727c --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,105 @@ +# Contributing to AnythingLLM + +AnythingLLM is an open-source project and we welcome contributions from the community. + +## Reporting Issues + +If you encounter a bug or have a feature request, please open an issue on the +[GitHub issue tracker](https://github.com/mintplex-labs/anything-llm). + +## Picking an issue + +We track issues on the GitHub issue tracker. If you are looking for something to +work on, check the [good first issue](https://github.com/mintplex-labs/anything-llm/contribute) label. These issues are typically the best described and have the smallest scope. There may be issues that are not labeled as good first issue, but are still a good starting point. + +If there's an issue you are interested in working on, please leave a comment on the issue. This will help us avoid duplicate work. Additionally, if you have questions about the issue, please ask them in the issue comments. We are happy to provide guidance on how to approach the issue. + +## Before you start + +Keep in mind that we are a small team and have limited resources. We will do our best to review and merge your PRs, but please be patient. Ultimately, **we become the maintainer** of your changes. It is our responsibility to make sure that the changes are working as expected and are of high quality as well as being compatible with the rest of the project both for existing users and for future users & features. + +Before you start working on an issue, please read the following so that you don't waste time on something that is not a good fit for the project or is more suitable for a personal fork. We would rather answer a comment on an issue than close a PR after you've spent time on it. Your time is valuable and we appreciate your time and effort to make AnythingLLM better. + +0. (most important) If you are making a PR that does not have a corresponding issue, **it will not be merged.** _The only exception to this is language translations._ + +1. If you are modifying the permission system for a new role or something custom, you are likely better off forking the project and building your own version since this is a core part of the project and is only to be maintained by the AnythingLLM team. + +2. Integrations (LLM, Vector DB, etc.) are reviewed at our discretion. We will eventually get to them. Do not expect us to merge your integration PR instantly since there are often many moving parts and we want to make sure we get it right. We will get to it! + +3. It is our discretion to merge or not merge a PR. We value every contribution, but we also value the quality of the code and the user experience we envision for the project. It is a fine line to walk when running a project like this and please understand that merging or not merging a PR is not a reflection of the quality of the contribution and is not personal. We will do our best to provide feedback on the PR and help you make the changes necessary to get it merged. + +4. **Security** is always important. If you have a security concern, please do not open an issue. Instead, please open a CVE on our designated reporting platform [Huntr](https://huntr.com) or contact us at [team@mintplexlabs.com](mailto:team@mintplexlabs.com). + +## Configuring Git + +First, fork the repository on GitHub, then clone your fork: + +```bash +git clone https://github.com//anything-llm.git +cd anything-llm +``` + +Then add the main repository as a remote: + +```bash +git remote add upstream https://github.com/mintplex-labs/anything-llm.git +git fetch upstream +``` + +## Setting up your development environment + +In the root of the repository, run: + +```bash +yarn setup +``` + +This will install the dependencies, set up the proper and expected ENV files for the project, and run the prisma setup script. +Next, run: + +```bash +yarn dev:all +``` +This will start the server, frontend, and collector in development mode. Changes to the code will be hot reloaded. + +## Best practices for pull requests + +For the best chance of having your pull request accepted, please follow these guidelines: + +1. Unit test all bug fixes and new features. Your code will not be merged if it + doesn't have tests. +1. If you change the public API, update the documentation in the `anythingllm-docs` repository. +1. Aim to minimize the number of changes in each pull request. Keep to solving + one problem at a time, when possible. +1. Before marking a pull request ready-for-review, do a self review of your code. + Is it clear why you are making the changes? Are the changes easy to understand? +1. Use [conventional commit messages](https://www.conventionalcommits.org/en/) as pull request titles. Examples: + * New feature: `feat: adding foo API` + * Bug fix: `fix: issue with foo API` + * Documentation change: `docs: adding foo API documentation` +1. If your pull request is a work in progress, leave the pull request as a draft. + We will assume the pull request is ready for review when it is opened. +1. When writing tests, test the error cases. Make sure they have understandable + error messages. + +## Project structure + +The core library is written in Node.js. There are additional sub-repositories for the embed widget and browser extension. These are not part of the core AnythingLLM project, but are maintained by the AnythingLLM team. + +* `server`: Node.js server source code +* `frontend`: React frontend source code +* `collector`: Python collector source code + +## Release process + +Changes to the core AnythingLLM project are released through the `master` branch. When a PR is merged into `master`, a new version of the package is published to Docker and GitHub Container Registry under the `latest` tag. + +When a new version is released, the following steps are taken a new image is built and pushed to Docker Hub and GitHub Container Registry under the assoicated version tag. Version tags are of the format `v..` and are pinned code, while `latest` is the latest version of the code at any point in time. + +### Desktop propogation + +Changes to the desktop app are downstream of the core AnythingLLM project. Releases of the desktop app are published at the same time as the core AnythingLLM project. Code from the core AnythingLLM project is copied into the desktop app into an Electron wrapper. The Electron wrapper that wraps around the core AnythingLLM project is **not** part of the core AnythingLLM project, but is maintained by the AnythingLLM team. + +## License + +By contributing to AnythingLLM (this repository), you agree to license your contributions under the MIT license. \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..cc42d1d080250fb38c47b81ed8f9fb1d64dc2965 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) Mintplex Labs Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000000000000000000000000000000000000..963fe71249967ea2591b0057396e522c0246dbe5 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,15 @@ +# Security Policy + +## Supported Versions + +Use this section to tell people about which versions of your project are +currently being supported with security updates. + +| Version | Supported | +| ------- | ------------------ | +| 0.1.x | :white_check_mark: | + + +## Reporting a Vulnerability + +If a security concern is found that you would like to disclose you can create a PR for it or if you would like to clear this issue before posting you can email [Core Mintplex Labs Team](mailto:team@mintplexlabs.com). diff --git a/cloud-deployments/aws/cloudformation/DEPLOY.md b/cloud-deployments/aws/cloudformation/DEPLOY.md new file mode 100644 index 0000000000000000000000000000000000000000..c7e84bc78d1513cf1909b76c3e6fdab2fd9a2d09 --- /dev/null +++ b/cloud-deployments/aws/cloudformation/DEPLOY.md @@ -0,0 +1,49 @@ +# How to deploy a private AnythingLLM instance on AWS + +With an AWS account you can easily deploy a private AnythingLLM instance on AWS. This will create a url that you can access from any browser over HTTP (HTTPS not supported). This single instance will run on your own keys and they will not be exposed - however if you want your instance to be protected it is highly recommend that you set a password once setup is complete. + +**Quick Launch (EASY)** +1. Log in to your AWS account +2. Open [CloudFormation](https://us-west-1.console.aws.amazon.com/cloudformation/home) +3. Ensure you are deploying in a geographic zone that is nearest to your physical location to reduce latency. +4. Click `Create Stack` + +![Create Stack](../../../images/screenshots/create_stack.png) + +5. Use the file `cloudformation_create_anythingllm.json` as your JSON template. + +![Upload Stack](../../../images/screenshots/upload.png) + +6. Click Deploy. +7. Wait for stack events to finish and be marked as `Completed` +8. View `Outputs` tab. + +![Stack Output](../../../images/screenshots/cf_outputs.png) + +9. Wait for all resources to be built. Now wait until instance is available on `[InstanceIP]:3001`. +This process may take up to 10 minutes. See **Note** below on how to visualize this process. + +The output of this cloudformation stack will be: +- 1 EC2 Instance +- 1 Security Group with 0.0.0.0/0 access on port 3001 +- 1 EC2 Instance Volume `gb2` of 10Gib minimum - customizable pre-deploy. + +**Requirements** +- An AWS account with billing information. + +## Please read this notice before submitting issues about your deployment + +**Note:** +Your instance will not be available instantly. Depending on the instance size you launched with it can take 5-10 minutes to fully boot up. + +If you want to check the instance's progress, navigate to [your deployed EC2 instances](https://us-west-1.console.aws.amazon.com/ec2/home) and connect to your instance via SSH in browser. + +Once connected run `sudo tail -f /var/log/cloud-init-output.log` and wait for the file to conclude deployment of the docker image. +You should see an output like this +``` +[+] Running 2/2 + ⠿ Network docker_anything-llm Created + ⠿ Container anything-llm Started +``` + +Additionally, your use of this deployment process means you are responsible for any costs of these AWS resources fully. \ No newline at end of file diff --git a/cloud-deployments/aws/cloudformation/aws_https_instructions.md b/cloud-deployments/aws/cloudformation/aws_https_instructions.md new file mode 100644 index 0000000000000000000000000000000000000000..26b0a6ba5ae9b8165b632385150773758a786377 --- /dev/null +++ b/cloud-deployments/aws/cloudformation/aws_https_instructions.md @@ -0,0 +1,118 @@ +# How to Configure HTTPS for Anything LLM AWS private deployment +Instructions for manual https configuration after generating and running the aws cloudformation template (aws_build_from_source_no_credentials.json). Tested on following browsers: Firefox version 119, Chrome version 118, Edge 118. + +**Requirements** +- Successful deployment of Amazon Linux 2023 EC2 instance with Docker container running Anything LLM +- Admin priv to configure Elastic IP for EC2 instance via AWS Management Console UI +- Admin priv to configure DNS services (i.e. AWS Route 53) via AWS Management Console UI +- Admin priv to configure EC2 Security Group rules via AWS Management Console UI + +## Step 1: Allocate and assign Elastic IP Address to your deployed EC2 instance +1. Follow AWS instructions on allocating EIP here: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html#using-instance-addressing-eips-allocating +2. Follow AWS instructions on assigning EIP to EC2 instance here: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html#using-instance-addressing-eips-associating + +## Step 2: Configure DNS A record to resolve to the previously assigned EC2 instance via EIP +These instructions assume that you already have a top-level domain configured and are using a subdomain +to access AnythingLLM. +1. Follow AWS instructions on routing traffic to EC2 instance here: https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-to-ec2-instance.html + +## Step 3: Install and enable nginx +These instructions are for CLI configuration and assume you are logged in to EC2 instance as the ec2-user. +1. $sudo yum install nginx -y +2. $sudo systemctl enable nginx && sudo systemctl start nginx + +## Step 4: Install certbot +These instructions are for CLI configuration and assume you are logged in to EC2 instance as the ec2-user. +1. $sudo yum install -y augeas-libs +2. $sudo python3 -m venv /opt/certbot/ +3. $sudo /opt/certbot/bin/pip install --upgrade pip +4. $sudo /opt/certbot/bin/pip install certbot certbot-nginx +5. $sudo ln -s /opt/certbot/bin/certbot /usr/bin/certbot + +## Step 5: Configure temporary Inbound Traffic Rule for Security Group to certbot DNS verification +1. Follow AWS instructions on creating inbound rule (http port 80 0.0.0.0/0) for EC2 security group here: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/working-with-security-groups.html#adding-security-group-rule + +## Step 6: Comment out default http NGINX proxy configuration +These instructions are for CLI configuration and assume you are logged in to EC2 instance as the ec2-user. +1. $sudo vi /etc/nginx/nginx.conf +2. In the nginx.conf file, comment out the default server block configuration for http/port 80. It should look something like the following: +``` +# server { +# listen 80; +# listen [::]:80; +# server_name _; +# root /usr/share/nginx/html; +# +# # Load configuration files for the default server block. +# include /etc/nginx/default.d/*.conf; +# +# error_page 404 /404.html; +# location = /404.html { +# } +# +# error_page 500 502 503 504 /50x.html; +# location = /50x.html { +# } +# } +``` +3. Enter ':wq' to save the changes to the nginx default config + +## Step 7: Create simple http proxy configuration for AnythingLLM +These instructions are for CLI configuration and assume you are logged in to EC2 instance as the ec2-user. +1. $sudo vi /etc/nginx/conf.d/anything.conf +2. Add the following configuration ensuring that you add your FQDN:. + +``` +server { + # Enable websocket connections for agent protocol. + location ~* ^/api/agent-invocation/(.*) { + proxy_pass http://0.0.0.0:3001; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + } + + listen 80; + server_name [insert FQDN here]; + location / { + # Prevent timeouts on long-running requests. + proxy_connect_timeout 605; + proxy_send_timeout 605; + proxy_read_timeout 605; + send_timeout 605; + keepalive_timeout 605; + + # Enable readable HTTP Streaming for LLM streamed responses + proxy_buffering off; + proxy_cache off; + + # Proxy your locally running service + proxy_pass http://0.0.0.0:3001; + } +} +``` +3. Enter ':wq' to save the changes to the anything config file + +## Step 8: Test nginx http proxy config and restart nginx service +These instructions are for CLI configuration and assume you are logged in to EC2 instance as the ec2-user. +1. $sudo nginx -t +2. $sudo systemctl restart nginx +3. Navigate to http://FQDN in a browser and you should be proxied to the AnythingLLM web UI. + +## Step 9: Generate/install cert +These instructions are for CLI configuration and assume you are logged in to EC2 instance as the ec2-user. +1. $sudo certbot --nginx -d [Insert FQDN here] + Example command: $sudo certbot --nginx -d anythingllm.exampleorganization.org + This command will generate the appropriate certificate files, write the files to /etc/letsencrypt/live/yourFQDN, and make updates to the nginx + configuration file for anythingllm located at /etc/nginx/conf.d/anything.llm +3. Enter the email address you would like to use for updates. +4. Accept the terms of service. +5. Accept or decline to receive communication from LetsEncrypt. + +## Step 10: Test Cert installation +1. $sudo cat /etc/nginx/conf.d/anything.conf +Your should see a completely updated configuration that includes https/443 and a redirect configuration for http/80. +2. Navigate to https://FQDN in a browser and you should be proxied to the AnythingLLM web UI. + +## Step 11: (Optional) Remove temporary Inbound Traffic Rule for Security Group to certbot DNS verification +1. Follow AWS instructions on deleting inbound rule (http port 80 0.0.0.0/0) for EC2 security group here: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/working-with-security-groups.html#deleting-security-group-rule diff --git a/cloud-deployments/aws/cloudformation/cloudformation_create_anythingllm.json b/cloud-deployments/aws/cloudformation/cloudformation_create_anythingllm.json new file mode 100644 index 0000000000000000000000000000000000000000..b10bbc2dbd9ad70feaaab08f9879ed2771d19980 --- /dev/null +++ b/cloud-deployments/aws/cloudformation/cloudformation_create_anythingllm.json @@ -0,0 +1,234 @@ +{ + "AWSTemplateFormatVersion": "2010-09-09", + "Description": "Create a stack that runs AnythingLLM on a single instance", + "Parameters": { + "InstanceType": { + "Description": "EC2 instance type", + "Type": "String", + "Default": "t3.small" + }, + "InstanceVolume": { + "Description": "Storage size of disk on Instance in GB", + "Type": "Number", + "Default": 10, + "MinValue": 4 + } + }, + "Resources": { + "AnythingLLMInstance": { + "Type": "AWS::EC2::Instance", + "Properties": { + "ImageId": { + "Fn::FindInMap": [ + "Region2AMI", + { + "Ref": "AWS::Region" + }, + "AMI" + ] + }, + "InstanceType": { + "Ref": "InstanceType" + }, + "SecurityGroupIds": [ + { + "Ref": "AnythingLLMInstanceSecurityGroup" + } + ], + "BlockDeviceMappings": [ + { + "DeviceName": { + "Fn::FindInMap": [ + "Region2AMI", + { + "Ref": "AWS::Region" + }, + "RootDeviceName" + ] + }, + "Ebs": { + "VolumeSize": { + "Ref": "InstanceVolume" + } + } + } + ], + "UserData": { + "Fn::Base64": { + "Fn::Join": [ + "", + [ + "Content-Type: multipart/mixed; boundary=\"//\"\n", + "MIME-Version: 1.0\n", + "\n", + "--//\n", + "Content-Type: text/cloud-config; charset=\"us-ascii\"\n", + "MIME-Version: 1.0\n", + "Content-Transfer-Encoding: 7bit\n", + "Content-Disposition: attachment; filename=\"cloud-config.txt\"\n", + "\n", + "\n", + "#cloud-config\n", + "cloud_final_modules:\n", + "- [scripts-user, once-per-instance]\n", + "\n", + "\n", + "--//\n", + "Content-Type: text/x-shellscript; charset=\"us-ascii\"\n", + "MIME-Version: 1.0\n", + "Content-Transfer-Encoding: 7bit\n", + "Content-Disposition: attachment; filename=\"userdata.txt\"\n", + "\n", + "\n", + "#!/bin/bash\n", + "# check output of userdata script with sudo tail -f /var/log/cloud-init-output.log\n", + "sudo yum install docker iptables -y\n", + "sudo iptables -A OUTPUT -m owner ! --uid-owner root -d 169.254.169.254 -j DROP\n", + "sudo systemctl enable docker\n", + "sudo systemctl start docker\n", + "mkdir -p /home/ec2-user/anythingllm\n", + "touch /home/ec2-user/anythingllm/.env\n", + "sudo chown ec2-user:ec2-user -R /home/ec2-user/anythingllm\n", + "docker pull mintplexlabs/anythingllm\n", + "docker run -d -p 3001:3001 --cap-add SYS_ADMIN -v /home/ec2-user/anythingllm:/app/server/storage -v /home/ec2-user/anythingllm/.env:/app/server/.env -e STORAGE_DIR=\"/app/server/storage\" mintplexlabs/anythingllm\n", + "echo \"Container ID: $(sudo docker ps --latest --quiet)\"\n", + "export ONLINE=$(curl -Is http://localhost:3001/api/ping | head -n 1|cut -d$' ' -f2)\n", + "echo \"Health check: $ONLINE\"\n", + "echo \"Setup complete! AnythingLLM instance is now online!\"\n", + "\n", + "--//--\n" + ] + ] + } + } + } + }, + "AnythingLLMInstanceSecurityGroup": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "AnythingLLM Instance Security Group", + "SecurityGroupIngress": [ + { + "IpProtocol": "tcp", + "FromPort": "22", + "ToPort": "22", + "CidrIp": "0.0.0.0/0" + }, + { + "IpProtocol": "tcp", + "FromPort": "3001", + "ToPort": "3001", + "CidrIp": "0.0.0.0/0" + }, + { + "IpProtocol": "tcp", + "FromPort": "3001", + "ToPort": "3001", + "CidrIpv6": "::/0" + } + ] + } + } + }, + "Outputs": { + "ServerIp": { + "Description": "IP address of the AnythingLLM instance", + "Value": { + "Fn::GetAtt": [ + "AnythingLLMInstance", + "PublicIp" + ] + } + }, + "ServerURL": { + "Description": "URL of the AnythingLLM server", + "Value": { + "Fn::Join": [ + "", + [ + "http://", + { + "Fn::GetAtt": [ + "AnythingLLMInstance", + "PublicIp" + ] + }, + ":3001" + ] + ] + } + } + }, + "Mappings": { + "Region2AMI": { + "ap-south-1": { + "AMI": "ami-0e6329e222e662a52", + "RootDeviceName": "/dev/xvda" + }, + "eu-north-1": { + "AMI": "ami-08c308b1bb265e927", + "RootDeviceName": "/dev/xvda" + }, + "eu-west-3": { + "AMI": "ami-069d1ea6bc64443f0", + "RootDeviceName": "/dev/xvda" + }, + "eu-west-2": { + "AMI": "ami-06a566ca43e14780d", + "RootDeviceName": "/dev/xvda" + }, + "eu-west-1": { + "AMI": "ami-0a8dc52684ee2fee2", + "RootDeviceName": "/dev/xvda" + }, + "ap-northeast-3": { + "AMI": "ami-0c8a89b455fae8513", + "RootDeviceName": "/dev/xvda" + }, + "ap-northeast-2": { + "AMI": "ami-0ff56409a6e8ea2a0", + "RootDeviceName": "/dev/xvda" + }, + "ap-northeast-1": { + "AMI": "ami-0ab0bbbd329f565e6", + "RootDeviceName": "/dev/xvda" + }, + "ca-central-1": { + "AMI": "ami-033c256a10931f206", + "RootDeviceName": "/dev/xvda" + }, + "sa-east-1": { + "AMI": "ami-0dabf4dab6b183eef", + "RootDeviceName": "/dev/xvda" + }, + "ap-southeast-1": { + "AMI": "ami-0dc5785603ad4ff54", + "RootDeviceName": "/dev/xvda" + }, + "ap-southeast-2": { + "AMI": "ami-0c5d61202c3b9c33e", + "RootDeviceName": "/dev/xvda" + }, + "eu-central-1": { + "AMI": "ami-004359656ecac6a95", + "RootDeviceName": "/dev/xvda" + }, + "us-east-1": { + "AMI": "ami-0cff7528ff583bf9a", + "RootDeviceName": "/dev/xvda" + }, + "us-east-2": { + "AMI": "ami-02238ac43d6385ab3", + "RootDeviceName": "/dev/xvda" + }, + "us-west-1": { + "AMI": "ami-01163e76c844a2129", + "RootDeviceName": "/dev/xvda" + }, + "us-west-2": { + "AMI": "ami-0ceecbb0f30a902a6", + "RootDeviceName": "/dev/xvda" + } + } + } +} \ No newline at end of file diff --git a/cloud-deployments/digitalocean/terraform/DEPLOY.md b/cloud-deployments/digitalocean/terraform/DEPLOY.md new file mode 100644 index 0000000000000000000000000000000000000000..e63231a0c196af818e0e9904aac6644b4799df42 --- /dev/null +++ b/cloud-deployments/digitalocean/terraform/DEPLOY.md @@ -0,0 +1,44 @@ +# How to deploy a private AnythingLLM instance on DigitalOcean using Terraform + +With a DigitalOcean account, you can easily deploy a private AnythingLLM instance using Terraform. This will create a URL that you can access from any browser over HTTP (HTTPS not supported). This single instance will run on your own keys, and they will not be exposed. However, if you want your instance to be protected, it is highly recommended that you set a password once setup is complete. + +The output of this Terraform configuration will be: +- 1 DigitalOcean Droplet +- An IP address to access your application + +**Requirements** +- An DigitalOcean account with billing information +- Terraform installed on your local machine + - Follow the instructions in the [official Terraform documentation](https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli) for your operating system. + +## How to deploy on DigitalOcean +Open your terminal and navigate to the `docker` folder +1. Create a `.env` file by cloning the `.env.example`. +2. Navigate to `digitalocean/terraform` folder. +3. Replace the token value in the provider "digitalocean" block in main.tf with your DigitalOcean API token. +4. Run the following commands to initialize Terraform, review the infrastructure changes, and apply them: + ``` + terraform init + terraform plan + terraform apply + ``` +Confirm the changes by typing yes when prompted. +5. Once the deployment is complete, Terraform will output the public IP address of your droplet. You can access your application using this IP address. + +## How to deploy on DigitalOcean +To delete the resources created by Terraform, run the following command in the terminal: +` +terraform destroy +` + +## Please read this notice before submitting issues about your deployment + +**Note:** +Your instance will not be available instantly. Depending on the instance size you launched with it can take anywhere from 5-10 minutes to fully boot up. + +If you want to check the instances progress, navigate to [your deployed instances](https://cloud.digitalocean.com/droplets) and connect to your instance via SSH in browser. + +Once connected run `sudo tail -f /var/log/cloud-init-output.log` and wait for the file to conclude deployment of the docker image. + + +Additionally, your use of this deployment process means you are responsible for any costs of these Digital Ocean resources fully. diff --git a/cloud-deployments/digitalocean/terraform/main.tf b/cloud-deployments/digitalocean/terraform/main.tf new file mode 100644 index 0000000000000000000000000000000000000000..7a76f57b21c8b7487605d872507b7e7e725f6a18 --- /dev/null +++ b/cloud-deployments/digitalocean/terraform/main.tf @@ -0,0 +1,52 @@ +terraform { + required_version = ">= 1.0.0" + + required_providers { + digitalocean = { + source = "digitalocean/digitalocean" + version = "~> 2.0" + } + } +} + +provider "digitalocean" { + # Add your DigitalOcean API token here + token = "DigitalOcean API token" +} + + +resource "digitalocean_droplet" "anything_llm_instance" { + image = "ubuntu-24-04-x64" + name = "anything-llm-instance" + region = "nyc3" + size = "s-2vcpu-2gb" + + user_data = templatefile("user_data.tp1", { + env_content = local.formatted_env_content + }) +} + +locals { + env_content = file("../../../docker/.env") + formatted_env_content = join("\n", [ + for line in split("\n", local.env_content) : + line + if !( + ( + substr(line, 0, 1) == "#" + ) || + ( + substr(line, 0, 3) == "UID" + ) || + ( + substr(line, 0, 3) == "GID" + ) || + ( + substr(line, 0, 11) == "CLOUD_BUILD" + ) || + ( + line == "" + ) + ) + ]) +} \ No newline at end of file diff --git a/cloud-deployments/digitalocean/terraform/outputs.tf b/cloud-deployments/digitalocean/terraform/outputs.tf new file mode 100644 index 0000000000000000000000000000000000000000..2b6d5595a5e740f2e8c5e9da01ecb5e864b1480f --- /dev/null +++ b/cloud-deployments/digitalocean/terraform/outputs.tf @@ -0,0 +1,4 @@ +output "ip_address" { + value = digitalocean_droplet.anything_llm_instance.ipv4_address + description = "The public IP address of your droplet application." +} \ No newline at end of file diff --git a/cloud-deployments/digitalocean/terraform/user_data.tp1 b/cloud-deployments/digitalocean/terraform/user_data.tp1 new file mode 100644 index 0000000000000000000000000000000000000000..1853f691c5e22df938939af5cc338744482ef909 --- /dev/null +++ b/cloud-deployments/digitalocean/terraform/user_data.tp1 @@ -0,0 +1,22 @@ +#!/bin/bash +# check output of userdata script with sudo tail -f /var/log/cloud-init-output.log + +sudo apt-get update +sudo apt-get install -y docker.io +sudo usermod -a -G docker ubuntu + +sudo systemctl enable docker +sudo systemctl start docker + +mkdir -p /home/anythingllm +cat </home/anythingllm/.env +${env_content} +EOF + +sudo docker pull mintplexlabs/anythingllm +sudo docker run -d -p 3001:3001 --cap-add SYS_ADMIN -v /home/anythingllm:/app/server/storage -v /home/anythingllm/.env:/app/server/.env -e STORAGE_DIR="/app/server/storage" mintplexlabs/anythingllm +echo "Container ID: $(sudo docker ps --latest --quiet)" + +export ONLINE=$(curl -Is http://localhost:3001/api/ping | head -n 1|cut -d$' ' -f2) +echo "Health check: $ONLINE" +echo "Setup complete! AnythingLLM instance is now online!" diff --git a/cloud-deployments/gcp/deployment/DEPLOY.md b/cloud-deployments/gcp/deployment/DEPLOY.md new file mode 100644 index 0000000000000000000000000000000000000000..754309ceb8ad7424c877d62047805a2a5a12f932 --- /dev/null +++ b/cloud-deployments/gcp/deployment/DEPLOY.md @@ -0,0 +1,54 @@ +# How to deploy a private AnythingLLM instance on GCP + +With a GCP account you can easily deploy a private AnythingLLM instance on GCP. This will create a url that you can access from any browser over HTTP (HTTPS not supported). This single instance will run on your own keys and they will not be exposed - however if you want your instance to be protected it is highly recommend that you set a password once setup is complete. + +The output of this cloudformation stack will be: +- 1 GCP VM +- 1 Security Group with 0.0.0.0/0 access on Ports 22 & 3001 +- 1 GCP VM Volume `gb2` of 10Gib minimum + +**Requirements** +- An GCP account with billing information. + +## How to deploy on GCP +Open your terminal +1. Log in to your GCP account using the following command: + ``` + gcloud auth login + ``` + +2. After successful login, Run the following command to create a deployment using the Deployment Manager CLI: + + ``` + + gcloud deployment-manager deployments create anything-llm-deployment --config gcp/deployment/gcp_deploy_anything_llm.yaml + + ``` + +Once you execute these steps, the CLI will initiate the deployment process on GCP based on your configuration file. You can monitor the deployment status and view the outputs using the Google Cloud Console or the Deployment Manager CLI commands. + +``` +gcloud compute instances get-serial-port-output anything-llm-instance +``` + +ssh into the instance + +``` +gcloud compute ssh anything-llm-instance +``` + +Delete the deployment +``` +gcloud deployment-manager deployments delete anything-llm-deployment +``` + +## Please read this notice before submitting issues about your deployment + +**Note:** +Your instance will not be available instantly. Depending on the instance size you launched with it can take anywhere from 5-10 minutes to fully boot up. + +If you want to check the instances progress, navigate to [your deployed instances](https://console.cloud.google.com/compute/instances) and connect to your instance via SSH in browser. + +Once connected run `sudo tail -f /var/log/cloud-init-output.log` and wait for the file to conclude deployment of the docker image. + +Additionally, your use of this deployment process means you are responsible for any costs of these GCP resources fully. diff --git a/cloud-deployments/gcp/deployment/gcp_deploy_anything_llm.yaml b/cloud-deployments/gcp/deployment/gcp_deploy_anything_llm.yaml new file mode 100644 index 0000000000000000000000000000000000000000..3f44d5af815b49db3158599b608108083fdc00a6 --- /dev/null +++ b/cloud-deployments/gcp/deployment/gcp_deploy_anything_llm.yaml @@ -0,0 +1,45 @@ +resources: + - name: anything-llm-instance + type: compute.v1.instance + properties: + zone: us-central1-a + machineType: zones/us-central1-a/machineTypes/n1-standard-1 + disks: + - deviceName: boot + type: PERSISTENT + boot: true + autoDelete: true + initializeParams: + sourceImage: projects/ubuntu-os-cloud/global/images/family/ubuntu-2004-lts + diskSizeGb: 10 + networkInterfaces: + - network: global/networks/default + accessConfigs: + - name: External NAT + type: ONE_TO_ONE_NAT + metadata: + items: + - key: startup-script + value: | + #!/bin/bash + # check output of userdata script with sudo tail -f /var/log/cloud-init-output.log + + sudo apt-get update + sudo apt-get install -y docker.io + sudo usermod -a -G docker ubuntu + sudo systemctl enable docker + sudo systemctl start docker + + mkdir -p /home/anythingllm + touch /home/anythingllm/.env + sudo chown -R ubuntu:ubuntu /home/anythingllm + + sudo docker pull mintplexlabs/anythingllm + sudo docker run -d -p 3001:3001 --cap-add SYS_ADMIN -v /home/anythingllm:/app/server/storage -v /home/anythingllm/.env:/app/server/.env -e STORAGE_DIR="/app/server/storage" mintplexlabs/anythingllm + echo "Container ID: $(sudo docker ps --latest --quiet)" + + export ONLINE=$(curl -Is http://localhost:3001/api/ping | head -n 1|cut -d$' ' -f2) + echo "Health check: $ONLINE" + + echo "Setup complete! AnythingLLM instance is now online!" + diff --git a/cloud-deployments/huggingface-spaces/Dockerfile b/cloud-deployments/huggingface-spaces/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..def87bffdd89beb4472e585c8dde57b1cd81eeae --- /dev/null +++ b/cloud-deployments/huggingface-spaces/Dockerfile @@ -0,0 +1,31 @@ +# With this dockerfile in a Huggingface space you will get an entire AnythingLLM instance running +# in your space with all features you would normally get from the docker based version of AnythingLLM. +# +# How to use +# - Login to https://huggingface.co/spaces +# - Click on "Create new Space" +# - Name the space and select "Docker" as the SDK w/ a blank template +# - The default 2vCPU/16GB machine is OK. The more the merrier. +# - Decide if you want your AnythingLLM Space public or private. +# **You might want to stay private until you at least set a password or enable multi-user mode** +# - Click "Create Space" +# - Click on "Settings" on top of page (https://huggingface.co/spaces///settings) +# - Scroll to "Persistent Storage" and select the lowest tier of now - you can upgrade if you run out. +# - Confirm and continue storage upgrade +# - Go to "Files" Tab (https://huggingface.co/spaces///tree/main) +# - Click "Add Files" +# - Upload this file or create a file named `Dockerfile` and copy-paste this content into it. "Commit to main" and save. +# - Your container will build and boot. You now have AnythingLLM on HuggingFace. Your data is stored in the persistent storage attached. +# Have Fun 🤗 +# Have issues? Check the logs on HuggingFace for clues. +FROM mintplexlabs/anythingllm:render + +USER root +RUN mkdir -p /data/storage +RUN ln -s /data/storage /storage +USER anythingllm + +ENV STORAGE_DIR="/data/storage" +ENV SERVER_PORT=7860 + +ENTRYPOINT ["/bin/bash", "/usr/local/bin/render-entrypoint.sh"] \ No newline at end of file diff --git a/cloud-deployments/k8/manifest.yaml b/cloud-deployments/k8/manifest.yaml new file mode 100644 index 0000000000000000000000000000000000000000..9aeef6a296deff1d2c2b5a5ed86458ece1d408bd --- /dev/null +++ b/cloud-deployments/k8/manifest.yaml @@ -0,0 +1,214 @@ +--- +apiVersion: v1 +kind: PersistentVolume +metadata: + name: anything-llm-volume + annotations: + pv.beta.kubernetes.io/uid: "1000" + pv.beta.kubernetes.io/gid: "1000" +spec: + storageClassName: gp2 + capacity: + storage: 5Gi + accessModes: + - ReadWriteOnce + awsElasticBlockStore: + # This is the volume UUID from AWS EC2 EBS Volumes list. + volumeID: "{{ anythingllm_awsElasticBlockStore_volumeID }}" + fsType: ext4 + nodeAffinity: + required: + nodeSelectorTerms: + - matchExpressions: + - key: topology.kubernetes.io/zone + operator: In + values: + - us-east-1c +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: anything-llm-volume-claim + namespace: "{{ namespace }}" +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 5Gi +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: anything-llm + namespace: "{{ namespace }}" + labels: + anything-llm: "true" +spec: + selector: + matchLabels: + k8s-app: anything-llm + replicas: 1 + strategy: + type: RollingUpdate + rollingUpdate: + maxSurge: 0% + maxUnavailable: 100% + template: + metadata: + labels: + anything-llm: "true" + k8s-app: anything-llm + app.kubernetes.io/name: anything-llm + app.kubernetes.io/part-of: anything-llm + annotations: + prometheus.io/scrape: "true" + prometheus.io/path: /metrics + prometheus.io/port: "9090" + spec: + serviceAccountName: "default" + terminationGracePeriodSeconds: 10 + securityContext: + fsGroup: 1000 + runAsNonRoot: true + runAsGroup: 1000 + runAsUser: 1000 + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: topology.kubernetes.io/zone + operator: In + values: + - us-east-1c + containers: + - name: anything-llm + resources: + limits: + memory: "1Gi" + cpu: "500m" + requests: + memory: "512Mi" + cpu: "250m" + imagePullPolicy: IfNotPresent + image: "mintplexlabs/anythingllm:render" + securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - SYS_ADMIN + runAsNonRoot: true + runAsGroup: 1000 + runAsUser: 1000 + command: + # Specify a command to override the Dockerfile's ENTRYPOINT. + - /bin/bash + - -c + - | + set -x -e + sleep 3 + echo "AWS_REGION: $AWS_REGION" + echo "SERVER_PORT: $SERVER_PORT" + echo "NODE_ENV: $NODE_ENV" + echo "STORAGE_DIR: $STORAGE_DIR" + { + cd /app/server/ && + npx prisma generate --schema=./prisma/schema.prisma && + npx prisma migrate deploy --schema=./prisma/schema.prisma && + node /app/server/index.js + echo "Server process exited with status $?" + } & + { + node /app/collector/index.js + echo "Collector process exited with status $?" + } & + wait -n + exit $? + readinessProbe: + httpGet: + path: /v1/api/health + port: 8888 + initialDelaySeconds: 15 + periodSeconds: 5 + successThreshold: 2 + livenessProbe: + httpGet: + path: /v1/api/health + port: 8888 + initialDelaySeconds: 15 + periodSeconds: 5 + failureThreshold: 3 + env: + - name: AWS_REGION + value: "{{ aws_region }}" + - name: AWS_ACCESS_KEY_ID + value: "{{ aws_access_id }}" + - name: AWS_SECRET_ACCESS_KEY + value: "{{ aws_access_secret }}" + - name: SERVER_PORT + value: "3001" + - name: JWT_SECRET + value: "my-random-string-for-seeding" # Please generate random string at least 12 chars long. + - name: STORAGE_DIR + value: "/storage" + - name: NODE_ENV + value: "production" + - name: UID + value: "1000" + - name: GID + value: "1000" + volumeMounts: + - name: anything-llm-server-storage-volume-mount + mountPath: /storage + volumes: + - name: anything-llm-server-storage-volume-mount + persistentVolumeClaim: + claimName: anything-llm-volume-claim +--- +# This serves the UI and the backend. +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: anything-llm-ingress + namespace: "{{ namespace }}" + annotations: + external-dns.alpha.kubernetes.io/hostname: "{{ namespace }}-chat.{{ base_domain }}" + kubernetes.io/ingress.class: "internal-ingress" + nginx.ingress.kubernetes.io/rewrite-target: / + ingress.kubernetes.io/ssl-redirect: "false" +spec: + rules: + - host: "{{ namespace }}-chat.{{ base_domain }}" + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: anything-llm-svc + port: + number: 3001 + tls: # < placing a host in the TLS config will indicate a cert should be created + - hosts: + - "{{ namespace }}-chat.{{ base_domain }}" + secretName: letsencrypt-prod +--- +apiVersion: v1 +kind: Service +metadata: + labels: + kubernetes.io/name: anything-llm + name: anything-llm-svc + namespace: "{{ namespace }}" +spec: + ports: + # "port" is external port, and "targetPort" is internal. + - port: 3301 + targetPort: 3001 + name: traffic + - port: 9090 + targetPort: 9090 + name: metrics + selector: + k8s-app: anything-llm \ No newline at end of file diff --git a/collector/.env.example b/collector/.env.example new file mode 100644 index 0000000000000000000000000000000000000000..ea4aba395d6007c4f25edd957dfd5589aed1a857 --- /dev/null +++ b/collector/.env.example @@ -0,0 +1 @@ +# Placeholder .env file for collector runtime diff --git a/collector/.gitignore b/collector/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..57436cefda4e8a1f9a6dd4fec95c622f811e2d53 --- /dev/null +++ b/collector/.gitignore @@ -0,0 +1,6 @@ +hotdir/* +!hotdir/__HOTDIR__.md +yarn-error.log +!yarn.lock +outputs +scripts diff --git a/collector/.nvmrc b/collector/.nvmrc new file mode 100644 index 0000000000000000000000000000000000000000..59f4a2f3ab843c5f1b4767ef0eae1d72a7597393 --- /dev/null +++ b/collector/.nvmrc @@ -0,0 +1 @@ +v18.13.0 \ No newline at end of file diff --git a/collector/__tests__/utils/extensions/YoutubeTranscript/YoutubeLoader/youtube-transcript.test.js b/collector/__tests__/utils/extensions/YoutubeTranscript/YoutubeLoader/youtube-transcript.test.js new file mode 100644 index 0000000000000000000000000000000000000000..1fca742fd5324a0eb7a80a2c2d98ec370077c734 --- /dev/null +++ b/collector/__tests__/utils/extensions/YoutubeTranscript/YoutubeLoader/youtube-transcript.test.js @@ -0,0 +1,16 @@ +const { YoutubeTranscript } = require("../../../../../utils/extensions/YoutubeTranscript/YoutubeLoader/youtube-transcript.js"); + +describe("YoutubeTranscript", () => { + it("should fetch transcript from YouTube video", async () => { + const videoId = "BJjsfNO5JTo"; + const transcript = await YoutubeTranscript.fetchTranscript(videoId, { + lang: "en", + }); + + expect(transcript).toBeDefined(); + expect(typeof transcript).toBe("string"); + expect(transcript.length).toBeGreaterThan(0); + // console.log("Success! Transcript length:", transcript.length); + // console.log("First 200 characters:", transcript.substring(0, 200) + "..."); + }, 30000); +}); diff --git a/collector/extensions/index.js b/collector/extensions/index.js new file mode 100644 index 0000000000000000000000000000000000000000..76c5aafd334c241c7fc098fd38fc1bb04234c7e2 --- /dev/null +++ b/collector/extensions/index.js @@ -0,0 +1,207 @@ +const { setDataSigner } = require("../middleware/setDataSigner"); +const { verifyPayloadIntegrity } = require("../middleware/verifyIntegrity"); +const { resolveRepoLoader, resolveRepoLoaderFunction } = require("../utils/extensions/RepoLoader"); +const { reqBody } = require("../utils/http"); +const { validURL } = require("../utils/url"); +const RESYNC_METHODS = require("./resync"); +const { loadObsidianVault } = require("../utils/extensions/ObsidianVault"); + +function extensions(app) { + if (!app) return; + + app.post( + "/ext/resync-source-document", + [verifyPayloadIntegrity, setDataSigner], + async function (request, response) { + try { + const { type, options } = reqBody(request); + if (!RESYNC_METHODS.hasOwnProperty(type)) throw new Error(`Type "${type}" is not a valid type to sync.`); + return await RESYNC_METHODS[type](options, response); + } catch (e) { + console.error(e); + response.status(200).json({ + success: false, + content: null, + reason: e.message || "A processing error occurred.", + }); + } + return; + } + ) + + app.post( + "/ext/:repo_platform-repo", + [verifyPayloadIntegrity, setDataSigner], + async function (request, response) { + try { + const loadRepo = resolveRepoLoaderFunction(request.params.repo_platform); + const { success, reason, data } = await loadRepo( + reqBody(request), + response, + ); + response.status(200).json({ + success, + reason, + data, + }); + } catch (e) { + console.error(e); + response.status(200).json({ + success: false, + reason: e.message || "A processing error occurred.", + data: {}, + }); + } + return; + } + ); + + // gets all branches for a specific repo + app.post( + "/ext/:repo_platform-repo/branches", + [verifyPayloadIntegrity], + async function (request, response) { + try { + const RepoLoader = resolveRepoLoader(request.params.repo_platform); + const allBranches = await new RepoLoader( + reqBody(request) + ).getRepoBranches(); + response.status(200).json({ + success: true, + reason: null, + data: { + branches: allBranches, + }, + }); + } catch (e) { + console.error(e); + response.status(400).json({ + success: false, + reason: e.message, + data: { + branches: [], + }, + }); + } + return; + } + ); + + app.post( + "/ext/youtube-transcript", + [verifyPayloadIntegrity], + async function (request, response) { + try { + const { loadYouTubeTranscript } = require("../utils/extensions/YoutubeTranscript"); + const { success, reason, data } = await loadYouTubeTranscript( + reqBody(request) + ); + response.status(200).json({ success, reason, data }); + } catch (e) { + console.error(e); + response.status(400).json({ + success: false, + reason: e.message, + data: { + title: null, + author: null, + }, + }); + } + return; + } + ); + + app.post( + "/ext/website-depth", + [verifyPayloadIntegrity], + async function (request, response) { + try { + const websiteDepth = require("../utils/extensions/WebsiteDepth"); + const { url, depth = 1, maxLinks = 20 } = reqBody(request); + if (!validURL(url)) throw new Error("Not a valid URL."); + const scrapedData = await websiteDepth(url, depth, maxLinks); + response.status(200).json({ success: true, data: scrapedData }); + } catch (e) { + console.error(e); + response.status(400).json({ success: false, reason: e.message }); + } + return; + } + ); + + app.post( + "/ext/confluence", + [verifyPayloadIntegrity, setDataSigner], + async function (request, response) { + try { + const { loadConfluence } = require("../utils/extensions/Confluence"); + const { success, reason, data } = await loadConfluence( + reqBody(request), + response + ); + response.status(200).json({ success, reason, data }); + } catch (e) { + console.error(e); + response.status(400).json({ + success: false, + reason: e.message, + data: { + title: null, + author: null, + }, + }); + } + return; + } + ); + + app.post( + "/ext/drupalwiki", + [verifyPayloadIntegrity, setDataSigner], + async function (request, response) { + try { + const { loadAndStoreSpaces } = require("../utils/extensions/DrupalWiki"); + const { success, reason, data } = await loadAndStoreSpaces( + reqBody(request), + response + ); + response.status(200).json({ success, reason, data }); + } catch (e) { + console.error(e); + response.status(400).json({ + success: false, + reason: e.message, + data: { + title: null, + author: null, + }, + }); + } + return; + } + ); + + app.post( + "/ext/obsidian/vault", + [verifyPayloadIntegrity, setDataSigner], + async function (request, response) { + try { + const { files } = reqBody(request); + const result = await loadObsidianVault({ files }); + response.status(200).json(result); + } catch (e) { + console.error(e); + response.status(400).json({ + success: false, + reason: e.message, + data: null, + }); + } + return; + } + ); +} + + +module.exports = extensions; \ No newline at end of file diff --git a/collector/extensions/resync/index.js b/collector/extensions/resync/index.js new file mode 100644 index 0000000000000000000000000000000000000000..3ca1f44ab6e71b3d3376f7a29b8b0f70926f4dee --- /dev/null +++ b/collector/extensions/resync/index.js @@ -0,0 +1,153 @@ +const { getLinkText } = require("../../processLink"); + +/** + * Fetches the content of a raw link. Returns the content as a text string of the link in question. + * @param {object} data - metadata from document (eg: link) + * @param {import("../../middleware/setDataSigner").ResponseWithSigner} response + */ +async function resyncLink({ link }, response) { + if (!link) throw new Error('Invalid link provided'); + try { + const { success, content = null } = await getLinkText(link); + if (!success) throw new Error(`Failed to sync link content. ${reason}`); + response.status(200).json({ success, content }); + } catch (e) { + console.error(e); + response.status(200).json({ + success: false, + content: null, + }); + } +} + +/** + * Fetches the content of a YouTube link. Returns the content as a text string of the video in question. + * We offer this as there may be some videos where a transcription could be manually edited after initial scraping + * but in general - transcriptions often never change. + * @param {object} data - metadata from document (eg: link) + * @param {import("../../middleware/setDataSigner").ResponseWithSigner} response + */ +async function resyncYouTube({ link }, response) { + if (!link) throw new Error('Invalid link provided'); + try { + const { fetchVideoTranscriptContent } = require("../../utils/extensions/YoutubeTranscript"); + const { success, reason, content } = await fetchVideoTranscriptContent({ url: link }); + if (!success) throw new Error(`Failed to sync YouTube video transcript. ${reason}`); + response.status(200).json({ success, content }); + } catch (e) { + console.error(e); + response.status(200).json({ + success: false, + content: null, + }); + } +} + +/** + * Fetches the content of a specific confluence page via its chunkSource. + * Returns the content as a text string of the page in question and only that page. + * @param {object} data - metadata from document (eg: chunkSource) + * @param {import("../../middleware/setDataSigner").ResponseWithSigner} response + */ +async function resyncConfluence({ chunkSource }, response) { + if (!chunkSource) throw new Error('Invalid source property provided'); + try { + // Confluence data is `payload` encrypted. So we need to expand its + // encrypted payload back into query params so we can reFetch the page with same access token/params. + const source = response.locals.encryptionWorker.expandPayload(chunkSource); + const { fetchConfluencePage } = require("../../utils/extensions/Confluence"); + const { success, reason, content } = await fetchConfluencePage({ + pageUrl: `https:${source.pathname}`, // need to add back the real protocol + baseUrl: source.searchParams.get('baseUrl'), + spaceKey: source.searchParams.get('spaceKey'), + accessToken: source.searchParams.get('token'), + username: source.searchParams.get('username'), + }); + + if (!success) throw new Error(`Failed to sync Confluence page content. ${reason}`); + response.status(200).json({ success, content }); + } catch (e) { + console.error(e); + response.status(200).json({ + success: false, + content: null, + }); + } +} + +/** + * Fetches the content of a specific confluence page via its chunkSource. + * Returns the content as a text string of the page in question and only that page. + * @param {object} data - metadata from document (eg: chunkSource) + * @param {import("../../middleware/setDataSigner").ResponseWithSigner} response + */ +async function resyncGithub({ chunkSource }, response) { + if (!chunkSource) throw new Error('Invalid source property provided'); + try { + // Github file data is `payload` encrypted (might contain PAT). So we need to expand its + // encrypted payload back into query params so we can reFetch the page with same access token/params. + const source = response.locals.encryptionWorker.expandPayload(chunkSource); + const { fetchGithubFile } = require("../../utils/extensions/RepoLoader/GithubRepo"); + const { success, reason, content } = await fetchGithubFile({ + repoUrl: `https:${source.pathname}`, // need to add back the real protocol + branch: source.searchParams.get('branch'), + accessToken: source.searchParams.get('pat'), + sourceFilePath: source.searchParams.get('path'), + }); + + if (!success) throw new Error(`Failed to sync GitHub file content. ${reason}`); + response.status(200).json({ success, content }); + } catch (e) { + console.error(e); + response.status(200).json({ + success: false, + content: null, + }); + } +} + + +/** + * Fetches the content of a specific DrupalWiki page via its chunkSource. + * Returns the content as a text string of the page in question and only that page. + * @param {object} data - metadata from document (eg: chunkSource) + * @param {import("../../middleware/setDataSigner").ResponseWithSigner} response + */ +async function resyncDrupalWiki({ chunkSource }, response) { + if (!chunkSource) throw new Error('Invalid source property provided'); + try { + // DrupalWiki data is `payload` encrypted. So we need to expand its + // encrypted payload back into query params so we can reFetch the page with same access token/params. + const source = response.locals.encryptionWorker.expandPayload(chunkSource); + const { loadPage } = require("../../utils/extensions/DrupalWiki"); + const { success, reason, content } = await loadPage({ + baseUrl: source.searchParams.get('baseUrl'), + pageId: source.searchParams.get('pageId'), + accessToken: source.searchParams.get('accessToken'), + }); + + if (!success) { + console.error(`Failed to sync DrupalWiki page content. ${reason}`); + response.status(200).json({ + success: false, + content: null, + }); + } else { + response.status(200).json({ success, content }); + } + } catch (e) { + console.error(e); + response.status(200).json({ + success: false, + content: null, + }); + } +} + +module.exports = { + link: resyncLink, + youtube: resyncYouTube, + confluence: resyncConfluence, + github: resyncGithub, + drupalwiki: resyncDrupalWiki, +} diff --git a/collector/hotdir/__HOTDIR__.md b/collector/hotdir/__HOTDIR__.md new file mode 100644 index 0000000000000000000000000000000000000000..8f20efc49ee05c185811497dab26e07313f17432 --- /dev/null +++ b/collector/hotdir/__HOTDIR__.md @@ -0,0 +1,3 @@ +### What is the "Hot directory" + +This is a pre-set file location that documents will be written to when uploaded by AnythingLLM. There is really no need to touch it. \ No newline at end of file diff --git a/collector/index.js b/collector/index.js new file mode 100644 index 0000000000000000000000000000000000000000..a0dd0e5644d50e10bbca674ab1ea18cdddf8739b --- /dev/null +++ b/collector/index.js @@ -0,0 +1,188 @@ +process.env.NODE_ENV === "development" + ? require("dotenv").config({ path: `.env.${process.env.NODE_ENV}` }) + : require("dotenv").config(); + +require("./utils/logger")(); +const express = require("express"); +const bodyParser = require("body-parser"); +const cors = require("cors"); +const path = require("path"); +const { ACCEPTED_MIMES } = require("./utils/constants"); +const { reqBody } = require("./utils/http"); +const { processSingleFile } = require("./processSingleFile"); +const { processLink, getLinkText } = require("./processLink"); +const { wipeCollectorStorage } = require("./utils/files"); +const extensions = require("./extensions"); +const { processRawText } = require("./processRawText"); +const { verifyPayloadIntegrity } = require("./middleware/verifyIntegrity"); +const app = express(); +const FILE_LIMIT = "3GB"; + +app.use(cors({ origin: true })); +app.use( + bodyParser.text({ limit: FILE_LIMIT }), + bodyParser.json({ limit: FILE_LIMIT }), + bodyParser.urlencoded({ + limit: FILE_LIMIT, + extended: true, + }) +); + +app.post( + "/process", + [verifyPayloadIntegrity], + async function (request, response) { + const { filename, options = {}, metadata = {} } = reqBody(request); + try { + const targetFilename = path + .normalize(filename) + .replace(/^(\.\.(\/|\\|$))+/, ""); + const { + success, + reason, + documents = [], + } = await processSingleFile(targetFilename, options, metadata); + response + .status(200) + .json({ filename: targetFilename, success, reason, documents }); + } catch (e) { + console.error(e); + response.status(200).json({ + filename: filename, + success: false, + reason: "A processing error occurred.", + documents: [], + }); + } + return; + } +); + +app.post( + "/parse", + [verifyPayloadIntegrity], + async function (request, response) { + const { filename, options = {} } = reqBody(request); + try { + const targetFilename = path + .normalize(filename) + .replace(/^(\.\.(\/|\\|$))+/, ""); + const { + success, + reason, + documents = [], + } = await processSingleFile(targetFilename, { + ...options, + parseOnly: true, + }); + response + .status(200) + .json({ filename: targetFilename, success, reason, documents }); + } catch (e) { + console.error(e); + response.status(200).json({ + filename: filename, + success: false, + reason: "A processing error occurred.", + documents: [], + }); + } + return; + } +); + +app.post( + "/process-link", + [verifyPayloadIntegrity], + async function (request, response) { + const { link, scraperHeaders = {}, metadata = {} } = reqBody(request); + try { + const { + success, + reason, + documents = [], + } = await processLink(link, scraperHeaders, metadata); + response.status(200).json({ url: link, success, reason, documents }); + } catch (e) { + console.error(e); + response.status(200).json({ + url: link, + success: false, + reason: "A processing error occurred.", + documents: [], + }); + } + return; + } +); + +app.post( + "/util/get-link", + [verifyPayloadIntegrity], + async function (request, response) { + const { link, captureAs = "text" } = reqBody(request); + try { + const { success, content = null } = await getLinkText(link, captureAs); + response.status(200).json({ url: link, success, content }); + } catch (e) { + console.error(e); + response.status(200).json({ + url: link, + success: false, + content: null, + }); + } + return; + } +); + +app.post( + "/process-raw-text", + [verifyPayloadIntegrity], + async function (request, response) { + const { textContent, metadata } = reqBody(request); + try { + const { + success, + reason, + documents = [], + } = await processRawText(textContent, metadata); + response + .status(200) + .json({ filename: metadata.title, success, reason, documents }); + } catch (e) { + console.error(e); + response.status(200).json({ + filename: metadata?.title || "Unknown-doc.txt", + success: false, + reason: "A processing error occurred.", + documents: [], + }); + } + return; + } +); + +extensions(app); + +app.get("/accepts", function (_, response) { + response.status(200).json(ACCEPTED_MIMES); +}); + +app.all("*", function (_, response) { + response.sendStatus(200); +}); + +app + .listen(8888, async () => { + await wipeCollectorStorage(); + console.log(`Document processor app listening on port 8888`); + }) + .on("error", function (_) { + process.once("SIGUSR2", function () { + process.kill(process.pid, "SIGUSR2"); + }); + process.on("SIGINT", function () { + process.kill(process.pid, "SIGINT"); + }); + }); diff --git a/collector/middleware/setDataSigner.js b/collector/middleware/setDataSigner.js new file mode 100644 index 0000000000000000000000000000000000000000..3ea3b2f811564199352f63c09fa1d09d669571d7 --- /dev/null +++ b/collector/middleware/setDataSigner.js @@ -0,0 +1,41 @@ +const { EncryptionWorker } = require("../utils/EncryptionWorker"); +const { CommunicationKey } = require("../utils/comKey"); + +/** + * Express Response Object interface with defined encryptionWorker attached to locals property. + * @typedef {import("express").Response & import("express").Response['locals'] & {encryptionWorker: EncryptionWorker} } ResponseWithSigner +*/ + +// You can use this middleware to assign the EncryptionWorker to the response locals +// property so that if can be used to encrypt/decrypt arbitrary data via response object. +// eg: Encrypting API keys in chunk sources. + +// The way this functions is that the rolling RSA Communication Key is used server-side to private-key encrypt the raw +// key of the persistent EncryptionManager credentials. Since EncryptionManager credentials do _not_ roll, we should not send them +// even between server<>collector in plaintext because if the user configured the server/collector to be public they could technically +// be exposing the key in transit via the X-Payload-Signer header. Even if this risk is minimal we should not do this. + +// This middleware uses the CommunicationKey public key to first decrypt the base64 representation of the EncryptionManager credentials +// and then loads that in to the EncryptionWorker as a buffer so we can use the same credentials across the system. Should we ever break the +// collector out into its own service this would still work without SSL/TLS. + +/** + * + * @param {import("express").Request} request + * @param {import("express").Response} response + * @param {import("express").NextFunction} next + */ +function setDataSigner(request, response, next) { + const comKey = new CommunicationKey(); + const encryptedPayloadSigner = request.header("X-Payload-Signer"); + if (!encryptedPayloadSigner) console.log('Failed to find signed-payload to set encryption worker! Encryption calls will fail.'); + + const decryptedPayloadSignerKey = comKey.decrypt(encryptedPayloadSigner); + const encryptionWorker = new EncryptionWorker(decryptedPayloadSignerKey); + response.locals.encryptionWorker = encryptionWorker; + next(); +} + +module.exports = { + setDataSigner +} \ No newline at end of file diff --git a/collector/middleware/verifyIntegrity.js b/collector/middleware/verifyIntegrity.js new file mode 100644 index 0000000000000000000000000000000000000000..93bb37ae7736cbb24c17bd225c9c78a3e0f84921 --- /dev/null +++ b/collector/middleware/verifyIntegrity.js @@ -0,0 +1,26 @@ +const { CommunicationKey } = require("../utils/comKey"); +const RuntimeSettings = require("../utils/runtimeSettings"); +const runtimeSettings = new RuntimeSettings(); + +function verifyPayloadIntegrity(request, response, next) { + const comKey = new CommunicationKey(); + if (process.env.NODE_ENV === "development") { + comKey.log('verifyPayloadIntegrity is skipped in development.'); + runtimeSettings.parseOptionsFromRequest(request); + next(); + return; + } + + const signature = request.header("X-Integrity"); + if (!signature) return response.status(400).json({ msg: 'Failed integrity signature check.' }) + + const validSignedPayload = comKey.verify(signature, request.body); + if (!validSignedPayload) return response.status(400).json({ msg: 'Failed integrity signature check.' }); + + runtimeSettings.parseOptionsFromRequest(request); + next(); +} + +module.exports = { + verifyPayloadIntegrity +} \ No newline at end of file diff --git a/collector/nodemon.json b/collector/nodemon.json new file mode 100644 index 0000000000000000000000000000000000000000..23e9d55e4835ea3fa8a12d4a35ba133e8818fce2 --- /dev/null +++ b/collector/nodemon.json @@ -0,0 +1,3 @@ +{ + "events": {} +} \ No newline at end of file diff --git a/collector/package.json b/collector/package.json new file mode 100644 index 0000000000000000000000000000000000000000..abd0cc98bf6c29b2a30888cbf8fec17597476a45 --- /dev/null +++ b/collector/package.json @@ -0,0 +1,55 @@ +{ + "name": "anything-llm-document-collector", + "version": "1.8.5", + "description": "Document collector server endpoints", + "main": "index.js", + "author": "Timothy Carambat (Mintplex Labs)", + "license": "MIT", + "private": false, + "engines": { + "node": ">=18.12.1" + }, + "scripts": { + "dev": "cross-env NODE_ENV=development nodemon --ignore hotdir --ignore storage --trace-warnings index.js", + "start": "cross-env NODE_ENV=production node index.js", + "lint": "yarn prettier --ignore-path ../.prettierignore --write ./processSingleFile ./processLink ./utils index.js" + }, + "dependencies": { + "@langchain/community": "^0.2.23", + "@xenova/transformers": "^2.14.0", + "bcrypt": "^5.1.0", + "body-parser": "^1.20.2", + "cors": "^2.8.5", + "dotenv": "^16.0.3", + "epub2": "^3.0.2", + "express": "^4.18.2", + "fluent-ffmpeg": "^2.1.2", + "html-to-text": "^9.0.5", + "ignore": "^5.3.0", + "js-tiktoken": "^1.0.8", + "langchain": "0.1.36", + "mammoth": "^1.6.0", + "mbox-parser": "^1.0.1", + "mime": "^3.0.0", + "moment": "^2.29.4", + "node-html-parser": "^6.1.13", + "node-xlsx": "^0.24.0", + "officeparser": "^4.0.5", + "openai": "4.95.1", + "pdf-parse": "^1.1.1", + "puppeteer": "~21.5.2", + "sharp": "^0.33.5", + "slugify": "^1.6.6", + "tesseract.js": "^6.0.0", + "url-pattern": "^1.0.3", + "uuid": "^9.0.0", + "wavefile": "^11.0.0", + "winston": "^3.13.0", + "youtubei.js": "^9.1.0" + }, + "devDependencies": { + "nodemon": "^2.0.22", + "prettier": "^2.4.1", + "cross-env": "^7.0.3" + } +} \ No newline at end of file diff --git a/collector/processLink/convert/generic.js b/collector/processLink/convert/generic.js new file mode 100644 index 0000000000000000000000000000000000000000..8f7560fb6de4516d6404af7bed8895fff7d69bf6 --- /dev/null +++ b/collector/processLink/convert/generic.js @@ -0,0 +1,190 @@ +const { v4 } = require("uuid"); +const { + PuppeteerWebBaseLoader, +} = require("langchain/document_loaders/web/puppeteer"); +const { writeToServerDocuments } = require("../../utils/files"); +const { tokenizeString } = require("../../utils/tokenizer"); +const { default: slugify } = require("slugify"); +const RuntimeSettings = require("../../utils/runtimeSettings"); + +/** + * Scrape a generic URL and return the content in the specified format + * @param {Object} config - The configuration object + * @param {string} config.link - The URL to scrape + * @param {('html' | 'text')} config.captureAs - The format to capture the page content as. Default is 'text' + * @param {boolean} config.processAsDocument - Whether to process the content as a document or return the content directly. Default is true + * @param {{[key: string]: string}} config.scraperHeaders - Custom headers to use when making the request + * @param {{[key: string]: string}} config.metadata - Metadata to use when creating the document + * @returns {Promise} - The content of the page + */ +async function scrapeGenericUrl({ + link, + captureAs = "text", + processAsDocument = true, + scraperHeaders = {}, + metadata = {}, +}) { + console.log(`-- Working URL ${link} => (${captureAs}) --`); + const content = await getPageContent({ + link, + captureAs, + headers: scraperHeaders, + }); + + if (!content.length) { + console.error(`Resulting URL content was empty at ${link}.`); + return { + success: false, + reason: `No URL content found at ${link}.`, + documents: [], + }; + } + + if (!processAsDocument) { + return { + success: true, + content, + }; + } + + const url = new URL(link); + const decodedPathname = decodeURIComponent(url.pathname); + const filename = `${url.hostname}${decodedPathname.replace(/\//g, "_")}`; + + const data = { + id: v4(), + url: "file://" + slugify(filename) + ".html", + title: metadata.title || slugify(filename) + ".html", + docAuthor: metadata.docAuthor || "no author found", + description: metadata.description || "No description found.", + docSource: metadata.docSource || "URL link uploaded by the user.", + chunkSource: `link://${link}`, + published: new Date().toLocaleString(), + wordCount: content.split(" ").length, + pageContent: content, + token_count_estimate: tokenizeString(content), + }; + + const document = writeToServerDocuments({ + data, + filename: `url-${slugify(filename)}-${data.id}`, + }); + console.log(`[SUCCESS]: URL ${link} converted & ready for embedding.\n`); + return { success: true, reason: null, documents: [document] }; +} + +/** + * Validate the headers object + * - Keys & Values must be strings and not empty + * - Assemble a new object with only the valid keys and values + * @param {{[key: string]: string}} headers - The headers object to validate + * @returns {{[key: string]: string}} - The validated headers object + */ +function validatedHeaders(headers = {}) { + try { + if (Object.keys(headers).length === 0) return {}; + let validHeaders = {}; + for (const key of Object.keys(headers)) { + if (!key?.trim()) continue; + if (typeof headers[key] !== "string" || !headers[key]?.trim()) continue; + validHeaders[key] = headers[key].trim(); + } + return validHeaders; + } catch (error) { + console.error("Error validating headers", error); + return {}; + } +} + +/** + * Get the content of a page + * @param {Object} config - The configuration object + * @param {string} config.link - The URL to get the content of + * @param {('html' | 'text')} config.captureAs - The format to capture the page content as. Default is 'text' + * @param {{[key: string]: string}} config.headers - Custom headers to use when making the request + * @returns {Promise} - The content of the page + */ +async function getPageContent({ link, captureAs = "text", headers = {} }) { + try { + let pageContents = []; + const runtimeSettings = new RuntimeSettings(); + const loader = new PuppeteerWebBaseLoader(link, { + launchOptions: { + headless: "new", + ignoreHTTPSErrors: true, + args: runtimeSettings.get("browserLaunchArgs"), + }, + gotoOptions: { + waitUntil: "networkidle2", + }, + async evaluate(page, browser) { + const result = await page.evaluate((captureAs) => { + if (captureAs === "text") return document.body.innerText; + if (captureAs === "html") return document.documentElement.innerHTML; + return document.body.innerText; + }, captureAs); + await browser.close(); + return result; + }, + }); + + // Override scrape method if headers are available + let overrideHeaders = validatedHeaders(headers); + if (Object.keys(overrideHeaders).length > 0) { + loader.scrape = async function () { + const { launch } = await PuppeteerWebBaseLoader.imports(); + const browser = await launch({ + headless: "new", + defaultViewport: null, + ignoreDefaultArgs: ["--disable-extensions"], + ...this.options?.launchOptions, + }); + const page = await browser.newPage(); + await page.setExtraHTTPHeaders(overrideHeaders); + + await page.goto(this.webPath, { + timeout: 180000, + waitUntil: "networkidle2", + ...this.options?.gotoOptions, + }); + + const bodyHTML = this.options?.evaluate + ? await this.options.evaluate(page, browser) + : await page.evaluate(() => document.body.innerHTML); + + await browser.close(); + return bodyHTML; + }; + } + + const docs = await loader.load(); + for (const doc of docs) pageContents.push(doc.pageContent); + return pageContents.join(" "); + } catch (error) { + console.error( + "getPageContent failed to be fetched by puppeteer - falling back to fetch!", + error + ); + } + + try { + const pageText = await fetch(link, { + method: "GET", + headers: { + "Content-Type": "text/plain", + "User-Agent": + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36,gzip(gfe)", + ...validatedHeaders(headers), + }, + }).then((res) => res.text()); + return pageText; + } catch (error) { + console.error("getPageContent failed to be fetched by any method.", error); + } + + return null; +} + +module.exports = { + scrapeGenericUrl, +}; diff --git a/collector/processLink/index.js b/collector/processLink/index.js new file mode 100644 index 0000000000000000000000000000000000000000..bcbbfb9e6596dee99c3df4084241cfc440f04b54 --- /dev/null +++ b/collector/processLink/index.js @@ -0,0 +1,42 @@ +const { validURL } = require("../utils/url"); +const { scrapeGenericUrl } = require("./convert/generic"); + +/** + * Process a link and return the text content. This util will save the link as a document + * so it can be used for embedding later. + * @param {string} link - The link to process + * @param {{[key: string]: string}} scraperHeaders - Custom headers to apply when scraping the link + * @param {Object} metadata - Optional metadata to attach to the document + * @returns {Promise<{success: boolean, content: string}>} - Response from collector + */ +async function processLink(link, scraperHeaders = {}, metadata = {}) { + if (!validURL(link)) return { success: false, reason: "Not a valid URL." }; + return await scrapeGenericUrl({ + link, + captureAs: "text", + processAsDocument: true, + scraperHeaders, + metadata, + }); +} + +/** + * Get the text content of a link - does not save the link as a document + * Mostly used in agentic flows/tools calls to get the text content of a link + * @param {string} link - The link to get the text content of + * @param {('html' | 'text' | 'json')} captureAs - The format to capture the page content as + * @returns {Promise<{success: boolean, content: string}>} - Response from collector + */ +async function getLinkText(link, captureAs = "text") { + if (!validURL(link)) return { success: false, reason: "Not a valid URL." }; + return await scrapeGenericUrl({ + link, + captureAs, + processAsDocument: false, + }); +} + +module.exports = { + processLink, + getLinkText, +}; diff --git a/collector/processRawText/index.js b/collector/processRawText/index.js new file mode 100644 index 0000000000000000000000000000000000000000..e3ce2ade2aacb88311e5077dca255cb7a61260cf --- /dev/null +++ b/collector/processRawText/index.js @@ -0,0 +1,69 @@ +const { v4 } = require("uuid"); +const { writeToServerDocuments } = require("../utils/files"); +const { tokenizeString } = require("../utils/tokenizer"); +const { default: slugify } = require("slugify"); + +// Will remove the last .extension from the input +// and stringify the input + move to lowercase. +function stripAndSlug(input) { + if (!input.includes('.')) return slugify(input, { lower: true }); + return slugify(input.split('.').slice(0, -1).join('-'), { lower: true }) +} + +const METADATA_KEYS = { + possible: { + url: ({ url, title }) => { + let validUrl; + try { + const u = new URL(url); + validUrl = ["https:", "http:"].includes(u.protocol); + } catch { } + + if (validUrl) return `web://${url.toLowerCase()}.website`; + return `file://${stripAndSlug(title)}.txt`; + }, + title: ({ title }) => `${stripAndSlug(title)}.txt`, + docAuthor: ({ docAuthor }) => { return typeof docAuthor === 'string' ? docAuthor : 'no author specified' }, + description: ({ description }) => { return typeof description === 'string' ? description : 'no description found' }, + docSource: ({ docSource }) => { return typeof docSource === 'string' ? docSource : 'no source set' }, + chunkSource: ({ chunkSource, title }) => { return typeof chunkSource === 'string' ? chunkSource : `${stripAndSlug(title)}.txt` }, + published: ({ published }) => { + if (isNaN(Number(published))) return new Date().toLocaleString(); + return new Date(Number(published)).toLocaleString() + }, + } +} + +async function processRawText(textContent, metadata) { + console.log(`-- Working Raw Text doc ${metadata.title} --`); + if (!textContent || textContent.length === 0) { + return { + success: false, + reason: "textContent was empty - nothing to process.", + documents: [], + }; + } + + const data = { + id: v4(), + url: METADATA_KEYS.possible.url(metadata), + title: METADATA_KEYS.possible.title(metadata), + docAuthor: METADATA_KEYS.possible.docAuthor(metadata), + description: METADATA_KEYS.possible.description(metadata), + docSource: METADATA_KEYS.possible.docSource(metadata), + chunkSource: METADATA_KEYS.possible.chunkSource(metadata), + published: METADATA_KEYS.possible.published(metadata), + wordCount: textContent.split(" ").length, + pageContent: textContent, + token_count_estimate: tokenizeString(textContent), + }; + + const document = writeToServerDocuments({ + data, + filename: `raw-${stripAndSlug(metadata.title)}-${data.id}`, + }); + console.log(`[SUCCESS]: Raw text and metadata saved & ready for embedding.\n`); + return { success: true, reason: null, documents: [document] }; +} + +module.exports = { processRawText } \ No newline at end of file diff --git a/collector/processSingleFile/convert/asAudio.js b/collector/processSingleFile/convert/asAudio.js new file mode 100644 index 0000000000000000000000000000000000000000..b4ddc8eb76d34bd7ad73d13e2c4d4e883e77999d --- /dev/null +++ b/collector/processSingleFile/convert/asAudio.js @@ -0,0 +1,79 @@ +const { v4 } = require("uuid"); +const { + createdDate, + trashFile, + writeToServerDocuments, +} = require("../../utils/files"); +const { tokenizeString } = require("../../utils/tokenizer"); +const { default: slugify } = require("slugify"); +const { LocalWhisper } = require("../../utils/WhisperProviders/localWhisper"); +const { OpenAiWhisper } = require("../../utils/WhisperProviders/OpenAiWhisper"); + +const WHISPER_PROVIDERS = { + openai: OpenAiWhisper, + local: LocalWhisper, +}; + +async function asAudio({ + fullFilePath = "", + filename = "", + options = {}, + metadata = {}, +}) { + const WhisperProvider = WHISPER_PROVIDERS.hasOwnProperty( + options?.whisperProvider + ) + ? WHISPER_PROVIDERS[options?.whisperProvider] + : WHISPER_PROVIDERS.local; + + console.log(`-- Working ${filename} --`); + const whisper = new WhisperProvider({ options }); + const { content, error } = await whisper.processFile(fullFilePath, filename); + + if (!!error) { + console.error(`Error encountered for parsing of ${filename}.`); + trashFile(fullFilePath); + return { + success: false, + reason: error, + documents: [], + }; + } + + if (!content?.length) { + console.error(`Resulting text content was empty for ${filename}.`); + trashFile(fullFilePath); + return { + success: false, + reason: `No text content found in ${filename}.`, + documents: [], + }; + } + + const data = { + id: v4(), + url: "file://" + fullFilePath, + title: metadata.title || filename, + docAuthor: metadata.docAuthor || "no author found", + description: metadata.description || "No description found.", + docSource: metadata.docSource || "audio file uploaded by the user.", + chunkSource: metadata.chunkSource || "", + published: createdDate(fullFilePath), + wordCount: content.split(" ").length, + pageContent: content, + token_count_estimate: tokenizeString(content), + }; + + const document = writeToServerDocuments({ + data, + filename: `${slugify(filename)}-${data.id}`, + options: { parseOnly: options.parseOnly }, + }); + trashFile(fullFilePath); + console.log( + `[SUCCESS]: ${filename} transcribed, converted & ready for embedding.\n` + ); + return { success: true, reason: null, documents: [document] }; +} + +module.exports = asAudio; diff --git a/collector/processSingleFile/convert/asDocx.js b/collector/processSingleFile/convert/asDocx.js new file mode 100644 index 0000000000000000000000000000000000000000..1f77e7720025e88bf2593f68211603d4921edf0b --- /dev/null +++ b/collector/processSingleFile/convert/asDocx.js @@ -0,0 +1,63 @@ +const { v4 } = require("uuid"); +const { DocxLoader } = require("langchain/document_loaders/fs/docx"); +const { + createdDate, + trashFile, + writeToServerDocuments, +} = require("../../utils/files"); +const { tokenizeString } = require("../../utils/tokenizer"); +const { default: slugify } = require("slugify"); + +async function asDocX({ + fullFilePath = "", + filename = "", + options = {}, + metadata = {}, +}) { + const loader = new DocxLoader(fullFilePath); + + console.log(`-- Working ${filename} --`); + let pageContent = []; + const docs = await loader.load(); + for (const doc of docs) { + console.log(`-- Parsing content from docx page --`); + if (!doc.pageContent.length) continue; + pageContent.push(doc.pageContent); + } + + if (!pageContent.length) { + console.error(`Resulting text content was empty for ${filename}.`); + trashFile(fullFilePath); + return { + success: false, + reason: `No text content found in ${filename}.`, + documents: [], + }; + } + + const content = pageContent.join(""); + const data = { + id: v4(), + url: "file://" + fullFilePath, + title: metadata.title || filename, + docAuthor: metadata.docAuthor || "no author found", + description: metadata.description || "No description found.", + docSource: metadata.docSource || "docx file uploaded by the user.", + chunkSource: metadata.chunkSource || "", + published: createdDate(fullFilePath), + wordCount: content.split(" ").length, + pageContent: content, + token_count_estimate: tokenizeString(content), + }; + + const document = writeToServerDocuments({ + data, + filename: `${slugify(filename)}-${data.id}`, + options: { parseOnly: options.parseOnly }, + }); + trashFile(fullFilePath); + console.log(`[SUCCESS]: ${filename} converted & ready for embedding.\n`); + return { success: true, reason: null, documents: [document] }; +} + +module.exports = asDocX; diff --git a/collector/processSingleFile/convert/asEPub.js b/collector/processSingleFile/convert/asEPub.js new file mode 100644 index 0000000000000000000000000000000000000000..283eb1e20189925c04692e333a337fe0dc9c17d1 --- /dev/null +++ b/collector/processSingleFile/convert/asEPub.js @@ -0,0 +1,61 @@ +const { v4 } = require("uuid"); +const { EPubLoader } = require("langchain/document_loaders/fs/epub"); +const { tokenizeString } = require("../../utils/tokenizer"); +const { + createdDate, + trashFile, + writeToServerDocuments, +} = require("../../utils/files"); +const { default: slugify } = require("slugify"); + +async function asEPub({ + fullFilePath = "", + filename = "", + options = {}, + metadata = {}, +}) { + let content = ""; + try { + const loader = new EPubLoader(fullFilePath, { splitChapters: false }); + const docs = await loader.load(); + docs.forEach((doc) => (content += doc.pageContent)); + } catch (err) { + console.error("Could not read epub file!", err); + } + + if (!content?.length) { + console.error(`Resulting text content was empty for ${filename}.`); + trashFile(fullFilePath); + return { + success: false, + reason: `No text content found in ${filename}.`, + documents: [], + }; + } + + console.log(`-- Working ${filename} --`); + const data = { + id: v4(), + url: "file://" + fullFilePath, + title: metadata.title || filename, + docAuthor: metadata.docAuthor || "Unknown", + description: metadata.description || "Unknown", + docSource: metadata.docSource || "epub file uploaded by the user.", + chunkSource: metadata.chunkSource || "", + published: createdDate(fullFilePath), + wordCount: content.split(" ").length, + pageContent: content, + token_count_estimate: tokenizeString(content), + }; + + const document = writeToServerDocuments({ + data, + filename: `${slugify(filename)}-${data.id}`, + options: { parseOnly: options.parseOnly }, + }); + trashFile(fullFilePath); + console.log(`[SUCCESS]: ${filename} converted & ready for embedding.\n`); + return { success: true, reason: null, documents: [document] }; +} + +module.exports = asEPub; diff --git a/collector/processSingleFile/convert/asImage.js b/collector/processSingleFile/convert/asImage.js new file mode 100644 index 0000000000000000000000000000000000000000..77052f14a1803f8c0597b2f4878d6796c9c13b7a --- /dev/null +++ b/collector/processSingleFile/convert/asImage.js @@ -0,0 +1,56 @@ +const { v4 } = require("uuid"); +const { tokenizeString } = require("../../utils/tokenizer"); +const { + createdDate, + trashFile, + writeToServerDocuments, +} = require("../../utils/files"); +const OCRLoader = require("../../utils/OCRLoader"); +const { default: slugify } = require("slugify"); + +async function asImage({ + fullFilePath = "", + filename = "", + options = {}, + metadata = {}, +}) { + let content = await new OCRLoader({ + targetLanguages: options?.ocr?.langList, + }).ocrImage(fullFilePath); + + if (!content?.length) { + console.error(`Resulting text content was empty for ${filename}.`); + trashFile(fullFilePath); + return { + success: false, + reason: `No text content found in ${filename}.`, + documents: [], + }; + } + + console.log(`-- Working ${filename} --`); + const data = { + id: v4(), + url: "file://" + fullFilePath, + title: metadata.title || filename, + docAuthor: metadata.docAuthor || "Unknown", + description: metadata.description || "Unknown", + docSource: metadata.docSource || "image file uploaded by the user.", + chunkSource: metadata.chunkSource || "", + published: createdDate(fullFilePath), + wordCount: content.split(" ").length, + pageContent: content, + token_count_estimate: tokenizeString(content), + }; + + const document = writeToServerDocuments({ + data, + filename: `${slugify(filename)}-${data.id}`, + options: { parseOnly: options.parseOnly }, + }); + trashFile(fullFilePath); + console.log(`[SUCCESS]: ${filename} converted & ready for embedding.\n`); + return { success: true, reason: null, documents: [document] }; +} + +module.exports = asImage; diff --git a/collector/processSingleFile/convert/asMbox.js b/collector/processSingleFile/convert/asMbox.js new file mode 100644 index 0000000000000000000000000000000000000000..8927616a019863fc2800ef8ab722b9a3cd3fd726 --- /dev/null +++ b/collector/processSingleFile/convert/asMbox.js @@ -0,0 +1,83 @@ +const { v4 } = require("uuid"); +const fs = require("fs"); +const { mboxParser } = require("mbox-parser"); +const { + createdDate, + trashFile, + writeToServerDocuments, +} = require("../../utils/files"); +const { tokenizeString } = require("../../utils/tokenizer"); +const { default: slugify } = require("slugify"); + +async function asMbox({ + fullFilePath = "", + filename = "", + options = {}, + metadata = {}, +}) { + console.log(`-- Working ${filename} --`); + + const mails = await mboxParser(fs.createReadStream(fullFilePath)) + .then((mails) => mails) + .catch((error) => { + console.log(`Could not parse mail items`, error); + return []; + }); + + if (!mails.length) { + console.error(`Resulting mail items was empty for ${filename}.`); + trashFile(fullFilePath); + return { + success: false, + reason: `No mail items found in ${filename}.`, + documents: [], + }; + } + + let item = 1; + const documents = []; + for (const mail of mails) { + if (!mail.hasOwnProperty("text")) continue; + + const content = mail.text; + if (!content) continue; + console.log( + `-- Working on message "${mail.subject || "Unknown subject"}" --` + ); + + const data = { + id: v4(), + url: "file://" + fullFilePath, + title: + metadata.title || + (mail?.subject + ? slugify(mail?.subject?.replace(".", "")) + ".mbox" + : `msg_${item}-${filename}`), + docAuthor: metadata.docAuthor || mail?.from?.text, + description: metadata.description || "No description found.", + docSource: + metadata.docSource || "Mbox message file uploaded by the user.", + chunkSource: metadata.chunkSource || "", + published: createdDate(fullFilePath), + wordCount: content.split(" ").length, + pageContent: content, + token_count_estimate: tokenizeString(content), + }; + + item++; + const document = writeToServerDocuments({ + data, + filename: `${slugify(filename)}-${data.id}-msg-${item}`, + options: { parseOnly: options.parseOnly }, + }); + documents.push(document); + } + + trashFile(fullFilePath); + console.log( + `[SUCCESS]: ${filename} messages converted & ready for embedding.\n` + ); + return { success: true, reason: null, documents }; +} + +module.exports = asMbox; diff --git a/collector/processSingleFile/convert/asOfficeMime.js b/collector/processSingleFile/convert/asOfficeMime.js new file mode 100644 index 0000000000000000000000000000000000000000..dcd084144ebcb3bbc4da1cf55c51d858e64dd310 --- /dev/null +++ b/collector/processSingleFile/convert/asOfficeMime.js @@ -0,0 +1,59 @@ +const { v4 } = require("uuid"); +const officeParser = require("officeparser"); +const { + createdDate, + trashFile, + writeToServerDocuments, +} = require("../../utils/files"); +const { tokenizeString } = require("../../utils/tokenizer"); +const { default: slugify } = require("slugify"); + +async function asOfficeMime({ + fullFilePath = "", + filename = "", + options = {}, + metadata = {}, +}) { + console.log(`-- Working ${filename} --`); + let content = ""; + try { + content = await officeParser.parseOfficeAsync(fullFilePath); + } catch (error) { + console.error(`Could not parse office or office-like file`, error); + } + + if (!content.length) { + console.error(`Resulting text content was empty for ${filename}.`); + trashFile(fullFilePath); + return { + success: false, + reason: `No text content found in ${filename}.`, + documents: [], + }; + } + + const data = { + id: v4(), + url: "file://" + fullFilePath, + title: metadata.title || filename, + docAuthor: metadata.docAuthor || "no author found", + description: metadata.description || "No description found.", + docSource: metadata.docSource || "Office file uploaded by the user.", + chunkSource: metadata.chunkSource || "", + published: createdDate(fullFilePath), + wordCount: content.split(" ").length, + pageContent: content, + token_count_estimate: tokenizeString(content), + }; + + const document = writeToServerDocuments({ + data, + filename: `${slugify(filename)}-${data.id}`, + options: { parseOnly: options.parseOnly }, + }); + trashFile(fullFilePath); + console.log(`[SUCCESS]: ${filename} converted & ready for embedding.\n`); + return { success: true, reason: null, documents: [document] }; +} + +module.exports = asOfficeMime; diff --git a/collector/processSingleFile/convert/asPDF/PDFLoader/index.js b/collector/processSingleFile/convert/asPDF/PDFLoader/index.js new file mode 100644 index 0000000000000000000000000000000000000000..26bcf2b1cc343f279b609ad507b514744345883d --- /dev/null +++ b/collector/processSingleFile/convert/asPDF/PDFLoader/index.js @@ -0,0 +1,97 @@ +const fs = require("fs").promises; + +class PDFLoader { + constructor(filePath, { splitPages = true } = {}) { + this.filePath = filePath; + this.splitPages = splitPages; + } + + async load() { + const buffer = await fs.readFile(this.filePath); + const { getDocument, version } = await this.getPdfJS(); + + const pdf = await getDocument({ + data: new Uint8Array(buffer), + useWorkerFetch: false, + isEvalSupported: false, + useSystemFonts: true, + }).promise; + + const meta = await pdf.getMetadata().catch(() => null); + const documents = []; + + for (let i = 1; i <= pdf.numPages; i += 1) { + const page = await pdf.getPage(i); + const content = await page.getTextContent(); + + if (content.items.length === 0) { + continue; + } + + let lastY; + const textItems = []; + for (const item of content.items) { + if ("str" in item) { + if (lastY === item.transform[5] || !lastY) { + textItems.push(item.str); + } else { + textItems.push(`\n${item.str}`); + } + lastY = item.transform[5]; + } + } + + const text = textItems.join(""); + documents.push({ + pageContent: text.trim(), + metadata: { + source: this.filePath, + pdf: { + version, + info: meta?.info, + metadata: meta?.metadata, + totalPages: pdf.numPages, + }, + loc: { pageNumber: i }, + }, + }); + } + + if (this.splitPages) { + return documents; + } + + if (documents.length === 0) { + return []; + } + + return [ + { + pageContent: documents.map((doc) => doc.pageContent).join("\n\n"), + metadata: { + source: this.filePath, + pdf: { + version, + info: meta?.info, + metadata: meta?.metadata, + totalPages: pdf.numPages, + }, + }, + }, + ]; + } + + async getPdfJS() { + try { + const pdfjs = await import("pdf-parse/lib/pdf.js/v1.10.100/build/pdf.js"); + return { getDocument: pdfjs.getDocument, version: pdfjs.version }; + } catch (e) { + console.error(e); + throw new Error( + "Failed to load pdf-parse. Please install it with eg. `npm install pdf-parse`." + ); + } + } +} + +module.exports = PDFLoader; diff --git a/collector/processSingleFile/convert/asPDF/index.js b/collector/processSingleFile/convert/asPDF/index.js new file mode 100644 index 0000000000000000000000000000000000000000..bacfdaf53bf515dce9770aa9069ba1af76190095 --- /dev/null +++ b/collector/processSingleFile/convert/asPDF/index.js @@ -0,0 +1,86 @@ +const { v4 } = require("uuid"); +const { + createdDate, + trashFile, + writeToServerDocuments, +} = require("../../../utils/files"); +const { tokenizeString } = require("../../../utils/tokenizer"); +const { default: slugify } = require("slugify"); +const PDFLoader = require("./PDFLoader"); +const OCRLoader = require("../../../utils/OCRLoader"); + +async function asPdf({ + fullFilePath = "", + filename = "", + options = {}, + metadata = {}, +}) { + const pdfLoader = new PDFLoader(fullFilePath, { + splitPages: true, + }); + + console.log(`-- Working ${filename} --`); + const pageContent = []; + let docs = await pdfLoader.load(); + + if (docs.length === 0) { + console.log( + `[asPDF] No text content found for ${filename}. Will attempt OCR parse.` + ); + docs = await new OCRLoader({ + targetLanguages: options?.ocr?.langList, + }).ocrPDF(fullFilePath); + } + + for (const doc of docs) { + console.log( + `-- Parsing content from pg ${ + doc.metadata?.loc?.pageNumber || "unknown" + } --` + ); + if (!doc.pageContent || !doc.pageContent.length) continue; + pageContent.push(doc.pageContent); + } + + if (!pageContent.length) { + console.error(`[asPDF] Resulting text content was empty for ${filename}.`); + trashFile(fullFilePath); + return { + success: false, + reason: `No text content found in ${filename}.`, + documents: [], + }; + } + + const content = pageContent.join(""); + const data = { + id: v4(), + url: "file://" + fullFilePath, + title: metadata.title || filename, + docAuthor: + metadata.docAuthor || + docs[0]?.metadata?.pdf?.info?.Creator || + "no author found", + description: + metadata.description || + docs[0]?.metadata?.pdf?.info?.Title || + "No description found.", + docSource: metadata.docSource || "pdf file uploaded by the user.", + chunkSource: metadata.chunkSource || "", + published: createdDate(fullFilePath), + wordCount: content.split(" ").length, + pageContent: content, + token_count_estimate: tokenizeString(content), + }; + + const document = writeToServerDocuments({ + data, + filename: `${slugify(filename)}-${data.id}`, + options: { parseOnly: options.parseOnly }, + }); + trashFile(fullFilePath); + console.log(`[SUCCESS]: ${filename} converted & ready for embedding.\n`); + return { success: true, reason: null, documents: [document] }; +} + +module.exports = asPdf; diff --git a/collector/processSingleFile/convert/asTxt.js b/collector/processSingleFile/convert/asTxt.js new file mode 100644 index 0000000000000000000000000000000000000000..d32cebce55184c2f02f11599b4531bc6dd3ed734 --- /dev/null +++ b/collector/processSingleFile/convert/asTxt.js @@ -0,0 +1,59 @@ +const { v4 } = require("uuid"); +const fs = require("fs"); +const { tokenizeString } = require("../../utils/tokenizer"); +const { + createdDate, + trashFile, + writeToServerDocuments, +} = require("../../utils/files"); +const { default: slugify } = require("slugify"); + +async function asTxt({ + fullFilePath = "", + filename = "", + options = {}, + metadata = {}, +}) { + let content = ""; + try { + content = fs.readFileSync(fullFilePath, "utf8"); + } catch (err) { + console.error("Could not read file!", err); + } + + if (!content?.length) { + console.error(`Resulting text content was empty for ${filename}.`); + trashFile(fullFilePath); + return { + success: false, + reason: `No text content found in ${filename}.`, + documents: [], + }; + } + + console.log(`-- Working ${filename} --`); + const data = { + id: v4(), + url: "file://" + fullFilePath, + title: metadata.title || filename, + docAuthor: metadata.docAuthor || "Unknown", + description: metadata.description || "Unknown", + docSource: metadata.docSource || "a text file uploaded by the user.", + chunkSource: metadata.chunkSource || "", + published: createdDate(fullFilePath), + wordCount: content.split(" ").length, + pageContent: content, + token_count_estimate: tokenizeString(content), + }; + + const document = writeToServerDocuments({ + data, + filename: `${slugify(filename)}-${data.id}`, + options: { parseOnly: options.parseOnly }, + }); + trashFile(fullFilePath); + console.log(`[SUCCESS]: ${filename} converted & ready for embedding.\n`); + return { success: true, reason: null, documents: [document] }; +} + +module.exports = asTxt; diff --git a/collector/processSingleFile/convert/asXlsx.js b/collector/processSingleFile/convert/asXlsx.js new file mode 100644 index 0000000000000000000000000000000000000000..c01bc86688ccdd3eea61453816d5a8506e4f5e86 --- /dev/null +++ b/collector/processSingleFile/convert/asXlsx.js @@ -0,0 +1,117 @@ +const { v4 } = require("uuid"); +const xlsx = require("node-xlsx").default; +const path = require("path"); +const fs = require("fs"); +const { + createdDate, + trashFile, + writeToServerDocuments, + documentsFolder, + directUploadsFolder, +} = require("../../utils/files"); +const { tokenizeString } = require("../../utils/tokenizer"); +const { default: slugify } = require("slugify"); + +function convertToCSV(data) { + return data + .map((row) => + row + .map((cell) => { + if (cell === null || cell === undefined) return ""; + if (typeof cell === "string" && cell.includes(",")) + return `"${cell}"`; + return cell; + }) + .join(",") + ) + .join("\n"); +} + +async function asXlsx({ + fullFilePath = "", + filename = "", + options = {}, + metadata = {}, +}) { + const documents = []; + const folderName = slugify(`${path.basename(filename)}-${v4().slice(0, 4)}`, { + lower: true, + trim: true, + }); + const outFolderPath = options.parseOnly + ? path.resolve(directUploadsFolder, folderName) + : path.resolve(documentsFolder, folderName); + + try { + const workSheetsFromFile = xlsx.parse(fullFilePath); + if (!fs.existsSync(outFolderPath)) + fs.mkdirSync(outFolderPath, { recursive: true }); + + for (const sheet of workSheetsFromFile) { + try { + const { name, data } = sheet; + const content = convertToCSV(data); + + if (!content?.length) { + console.warn(`Sheet "${name}" is empty. Skipping.`); + continue; + } + + console.log(`-- Processing sheet: ${name} --`); + const sheetData = { + id: v4(), + url: `file://${path.join(outFolderPath, `${slugify(name)}.csv`)}`, + title: metadata.title || `${filename} - Sheet:${name}`, + docAuthor: metadata.docAuthor || "Unknown", + description: + metadata.description || `Spreadsheet data from sheet: ${name}`, + docSource: metadata.docSource || "an xlsx file uploaded by the user.", + chunkSource: metadata.chunkSource || "", + published: createdDate(fullFilePath), + wordCount: content.split(/\s+/).length, + pageContent: content, + token_count_estimate: tokenizeString(content), + }; + + const document = writeToServerDocuments({ + data: sheetData, + filename: `sheet-${slugify(name)}`, + destinationOverride: outFolderPath, + options: { parseOnly: options.parseOnly }, + }); + documents.push(document); + console.log( + `[SUCCESS]: Sheet "${name}" converted & ready for embedding.` + ); + } catch (err) { + console.error(`Error processing sheet "${name}":`, err); + continue; + } + } + } catch (err) { + console.error("Could not process xlsx file!", err); + return { + success: false, + reason: `Error processing ${filename}: ${err.message}`, + documents: [], + }; + } finally { + trashFile(fullFilePath); + } + + if (documents.length === 0) { + console.error(`No valid sheets found in ${filename}.`); + return { + success: false, + reason: `No valid sheets found in ${filename}.`, + documents: [], + }; + } + + console.log( + `[SUCCESS]: ${filename} fully processed. Created ${documents.length} document(s).\n` + ); + return { success: true, reason: null, documents }; +} + +module.exports = asXlsx; diff --git a/collector/processSingleFile/index.js b/collector/processSingleFile/index.js new file mode 100644 index 0000000000000000000000000000000000000000..3bf31a700046f71c1f8297ea7335aef1a3ca75e0 --- /dev/null +++ b/collector/processSingleFile/index.js @@ -0,0 +1,86 @@ +const path = require("path"); +const fs = require("fs"); +const { + WATCH_DIRECTORY, + SUPPORTED_FILETYPE_CONVERTERS, +} = require("../utils/constants"); +const { + trashFile, + isTextType, + normalizePath, + isWithin, +} = require("../utils/files"); +const RESERVED_FILES = ["__HOTDIR__.md"]; + +/** + * Process a single file and return the documents + * @param {string} targetFilename - The filename to process + * @param {Object} options - The options for the file processing + * @param {Object} metadata - The metadata for the file processing + * @returns {Promise<{success: boolean, reason: string, documents: Object[]}>} - The documents from the file processing + */ +async function processSingleFile(targetFilename, options = {}, metadata = {}) { + const fullFilePath = path.resolve( + WATCH_DIRECTORY, + normalizePath(targetFilename) + ); + if (!isWithin(path.resolve(WATCH_DIRECTORY), fullFilePath)) + return { + success: false, + reason: "Filename is a not a valid path to process.", + documents: [], + }; + + if (RESERVED_FILES.includes(targetFilename)) + return { + success: false, + reason: "Filename is a reserved filename and cannot be processed.", + documents: [], + }; + if (!fs.existsSync(fullFilePath)) + return { + success: false, + reason: "File does not exist in upload directory.", + documents: [], + }; + + const fileExtension = path.extname(fullFilePath).toLowerCase(); + if (fullFilePath.includes(".") && !fileExtension) { + return { + success: false, + reason: `No file extension found. This file cannot be processed.`, + documents: [], + }; + } + + let processFileAs = fileExtension; + if (!SUPPORTED_FILETYPE_CONVERTERS.hasOwnProperty(fileExtension)) { + if (isTextType(fullFilePath)) { + console.log( + `\x1b[33m[Collector]\x1b[0m The provided filetype of ${fileExtension} does not have a preset and will be processed as .txt.` + ); + processFileAs = ".txt"; + } else { + trashFile(fullFilePath); + return { + success: false, + reason: `File extension ${fileExtension} not supported for parsing and cannot be assumed as text file type.`, + documents: [], + }; + } + } + + const FileTypeProcessor = require(SUPPORTED_FILETYPE_CONVERTERS[ + processFileAs + ]); + return await FileTypeProcessor({ + fullFilePath, + filename: targetFilename, + options, + metadata, + }); +} + +module.exports = { + processSingleFile, +}; diff --git a/collector/storage/.gitignore b/collector/storage/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..845482b730c9bf9c1b122feed1af735049be47fd --- /dev/null +++ b/collector/storage/.gitignore @@ -0,0 +1,2 @@ +tmp/* +!tmp/.placeholder \ No newline at end of file diff --git a/collector/storage/tmp/.placeholder b/collector/storage/tmp/.placeholder new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/collector/utils/EncryptionWorker/index.js b/collector/utils/EncryptionWorker/index.js new file mode 100644 index 0000000000000000000000000000000000000000..ddc2773314701158a1f41eade073ee5fb99022d2 --- /dev/null +++ b/collector/utils/EncryptionWorker/index.js @@ -0,0 +1,77 @@ +const crypto = require("crypto"); + +// Differs from EncryptionManager in that is does not set or define the keys that will be used +// to encrypt or read data and it must be told the key (as base64 string) explicitly that will be used and is provided to +// the class on creation. This key should be the same `key` that is used by the EncryptionManager class. +class EncryptionWorker { + constructor(presetKeyBase64 = "") { + this.key = Buffer.from(presetKeyBase64, "base64"); + this.algorithm = "aes-256-cbc"; + this.separator = ":"; + } + + log(text, ...args) { + console.log(`\x1b[36m[EncryptionManager]\x1b[0m ${text}`, ...args); + } + + /** + * Give a chunk source, parse its payload query param and expand that object back into the URL + * as additional query params + * @param {string} chunkSource + * @returns {URL} Javascript URL object with query params decrypted from payload query param. + */ + expandPayload(chunkSource = "") { + try { + const url = new URL(chunkSource); + if (!url.searchParams.has("payload")) return url; + + const decryptedPayload = this.decrypt(url.searchParams.get("payload")); + const encodedParams = JSON.parse(decryptedPayload); + url.searchParams.delete("payload"); // remove payload prop + + // Add all query params needed to replay as query params + Object.entries(encodedParams).forEach(([key, value]) => + url.searchParams.append(key, value) + ); + return url; + } catch (e) { + console.error(e); + } + return new URL(chunkSource); + } + + encrypt(plainTextString = null) { + try { + if (!plainTextString) + throw new Error("Empty string is not valid for this method."); + const iv = crypto.randomBytes(16); + const cipher = crypto.createCipheriv(this.algorithm, this.key, iv); + const encrypted = cipher.update(plainTextString, "utf8", "hex"); + return [ + encrypted + cipher.final("hex"), + Buffer.from(iv).toString("hex"), + ].join(this.separator); + } catch (e) { + this.log(e); + return null; + } + } + + decrypt(encryptedString) { + try { + const [encrypted, iv] = encryptedString.split(this.separator); + if (!iv) throw new Error("IV not found"); + const decipher = crypto.createDecipheriv( + this.algorithm, + this.key, + Buffer.from(iv, "hex") + ); + return decipher.update(encrypted, "hex", "utf8") + decipher.final("utf8"); + } catch (e) { + this.log(e); + return null; + } + } +} + +module.exports = { EncryptionWorker }; diff --git a/collector/utils/OCRLoader/index.js b/collector/utils/OCRLoader/index.js new file mode 100644 index 0000000000000000000000000000000000000000..1c952d6f887c2b8ed8f5cc56521e4d731cedeb90 --- /dev/null +++ b/collector/utils/OCRLoader/index.js @@ -0,0 +1,354 @@ +const fs = require("fs"); +const os = require("os"); +const path = require("path"); +const { VALID_LANGUAGE_CODES } = require("./validLangs"); + +class OCRLoader { + /** + * The language code(s) to use for the OCR. + * @type {string[]} + */ + language; + /** + * The cache directory for the OCR. + * @type {string} + */ + cacheDir; + + /** + * The constructor for the OCRLoader. + * @param {Object} options - The options for the OCRLoader. + * @param {string} options.targetLanguages - The target languages to use for the OCR as a comma separated string. eg: "eng,deu,..." + */ + constructor({ targetLanguages = "eng" } = {}) { + this.language = this.parseLanguages(targetLanguages); + this.cacheDir = path.resolve( + process.env.STORAGE_DIR + ? path.resolve(process.env.STORAGE_DIR, `models`, `tesseract`) + : path.resolve(__dirname, `../../../server/storage/models/tesseract`) + ); + + // Ensure the cache directory exists or else Tesseract will persist the cache in the default location. + if (!fs.existsSync(this.cacheDir)) + fs.mkdirSync(this.cacheDir, { recursive: true }); + this.log( + `OCRLoader initialized with language support for:`, + this.language.map((lang) => VALID_LANGUAGE_CODES[lang]).join(", ") + ); + } + + /** + * Parses the language code from a provided comma separated string of language codes. + * @param {string} language - The language code to parse. + * @returns {string[]} The parsed language code. + */ + parseLanguages(language = null) { + try { + if (!language || typeof language !== "string") return ["eng"]; + const langList = language + .split(",") + .map((lang) => (lang.trim() !== "" ? lang.trim() : null)) + .filter(Boolean) + .filter((lang) => VALID_LANGUAGE_CODES.hasOwnProperty(lang)); + if (langList.length === 0) return ["eng"]; + return langList; + } catch (e) { + this.log(`Error parsing languages: ${e.message}`, e.stack); + return ["eng"]; + } + } + + log(text, ...args) { + console.log(`\x1b[36m[OCRLoader]\x1b[0m ${text}`, ...args); + } + + /** + * Loads a PDF file and returns an array of documents. + * This function is reserved to parsing for SCANNED documents - digital documents are not supported in this function + * @returns {Promise<{pageContent: string, metadata: object}[]>} An array of documents with page content and metadata. + */ + async ocrPDF( + filePath, + { maxExecutionTime = 300_000, batchSize = 10, maxWorkers = null } = {} + ) { + if ( + !filePath || + !fs.existsSync(filePath) || + !fs.statSync(filePath).isFile() + ) { + this.log(`File ${filePath} does not exist. Skipping OCR.`); + return []; + } + + const documentTitle = path.basename(filePath); + this.log(`Starting OCR of ${documentTitle}`); + const pdfjs = await import("pdf-parse/lib/pdf.js/v2.0.550/build/pdf.js"); + let buffer = fs.readFileSync(filePath); + + const pdfDocument = await pdfjs.getDocument({ data: buffer }); + + const documents = []; + const meta = await pdfDocument.getMetadata().catch(() => null); + const metadata = { + source: filePath, + pdf: { + version: "v2.0.550", + info: meta?.info, + metadata: meta?.metadata, + totalPages: pdfDocument.numPages, + }, + }; + + const pdfSharp = new PDFSharp({ + validOps: [ + pdfjs.OPS.paintJpegXObject, + pdfjs.OPS.paintImageXObject, + pdfjs.OPS.paintInlineImageXObject, + ], + }); + await pdfSharp.init(); + + const { createWorker, OEM } = require("tesseract.js"); + const BATCH_SIZE = batchSize; + const MAX_EXECUTION_TIME = maxExecutionTime; + const NUM_WORKERS = maxWorkers ?? Math.min(os.cpus().length, 4); + const totalPages = pdfDocument.numPages; + const workerPool = await Promise.all( + Array(NUM_WORKERS) + .fill(0) + .map(() => + createWorker(this.language, OEM.LSTM_ONLY, { + cachePath: this.cacheDir, + }) + ) + ); + + const startTime = Date.now(); + try { + this.log("Bootstrapping OCR completed successfully!", { + MAX_EXECUTION_TIME_MS: MAX_EXECUTION_TIME, + BATCH_SIZE, + MAX_CONCURRENT_WORKERS: NUM_WORKERS, + TOTAL_PAGES: totalPages, + }); + const timeoutPromise = new Promise((_, reject) => { + setTimeout(() => { + reject( + new Error( + `OCR job took too long to complete (${ + MAX_EXECUTION_TIME / 1000 + } seconds)` + ) + ); + }, MAX_EXECUTION_TIME); + }); + + const processPages = async () => { + for ( + let startPage = 1; + startPage <= totalPages; + startPage += BATCH_SIZE + ) { + const endPage = Math.min(startPage + BATCH_SIZE - 1, totalPages); + const pageNumbers = Array.from( + { length: endPage - startPage + 1 }, + (_, i) => startPage + i + ); + this.log(`Working on pages ${startPage} - ${endPage}`); + + const pageQueue = [...pageNumbers]; + const results = []; + const workerPromises = workerPool.map(async (worker, workerIndex) => { + while (pageQueue.length > 0) { + const pageNum = pageQueue.shift(); + this.log( + `\x1b[34m[Worker ${ + workerIndex + 1 + }]\x1b[0m assigned pg${pageNum}` + ); + const page = await pdfDocument.getPage(pageNum); + const imageBuffer = await pdfSharp.pageToBuffer({ page }); + if (!imageBuffer) continue; + const { data } = await worker.recognize(imageBuffer, {}, "text"); + this.log( + `✅ \x1b[34m[Worker ${ + workerIndex + 1 + }]\x1b[0m completed pg${pageNum}` + ); + results.push({ + pageContent: data.text, + metadata: { + ...metadata, + loc: { pageNumber: pageNum }, + }, + }); + } + }); + + await Promise.all(workerPromises); + documents.push( + ...results.sort( + (a, b) => a.metadata.loc.pageNumber - b.metadata.loc.pageNumber + ) + ); + } + return documents; + }; + + await Promise.race([timeoutPromise, processPages()]); + } catch (e) { + this.log(`Error: ${e.message}`, e.stack); + } finally { + global.Image = undefined; + await Promise.all(workerPool.map((worker) => worker.terminate())); + } + + this.log(`Completed OCR of ${documentTitle}!`, { + documentsParsed: documents.length, + totalPages: totalPages, + executionTime: `${((Date.now() - startTime) / 1000).toFixed(2)}s`, + }); + return documents; + } + + /** + * Loads an image file and returns the OCRed text. + * @param {string} filePath - The path to the image file. + * @param {Object} options - The options for the OCR. + * @param {number} options.maxExecutionTime - The maximum execution time of the OCR in milliseconds. + * @returns {Promise} The OCRed text. + */ + async ocrImage(filePath, { maxExecutionTime = 300_000 } = {}) { + let content = ""; + let worker = null; + if ( + !filePath || + !fs.existsSync(filePath) || + !fs.statSync(filePath).isFile() + ) { + this.log(`File ${filePath} does not exist. Skipping OCR.`); + return null; + } + + const documentTitle = path.basename(filePath); + try { + this.log(`Starting OCR of ${documentTitle}`); + const startTime = Date.now(); + const { createWorker, OEM } = require("tesseract.js"); + worker = await createWorker(this.language, OEM.LSTM_ONLY, { + cachePath: this.cacheDir, + }); + + // Race the timeout with the OCR + const timeoutPromise = new Promise((_, reject) => { + setTimeout(() => { + reject( + new Error( + `OCR job took too long to complete (${ + maxExecutionTime / 1000 + } seconds)` + ) + ); + }, maxExecutionTime); + }); + + const processImage = async () => { + const { data } = await worker.recognize(filePath, {}, "text"); + content = data.text; + }; + + await Promise.race([timeoutPromise, processImage()]); + this.log(`Completed OCR of ${documentTitle}!`, { + executionTime: `${((Date.now() - startTime) / 1000).toFixed(2)}s`, + }); + + return content; + } catch (e) { + this.log(`Error: ${e.message}`); + return null; + } finally { + if (!worker) return; + await worker.terminate(); + } + } +} + +/** + * Converts a PDF page to a buffer using Sharp. + * @param {Object} options - The options for the Sharp PDF page object. + * @param {Object} options.page - The PDFJS page proxy object. + * @returns {Promise} The buffer of the page. + */ +class PDFSharp { + constructor({ validOps = [] } = {}) { + this.sharp = null; + this.validOps = validOps; + } + + log(text, ...args) { + console.log(`\x1b[36m[PDFSharp]\x1b[0m ${text}`, ...args); + } + + async init() { + this.sharp = (await import("sharp")).default; + } + + /** + * Converts a PDF page to a buffer. + * @param {Object} options - The options for the Sharp PDF page object. + * @param {Object} options.page - The PDFJS page proxy object. + * @returns {Promise} The buffer of the page. + */ + async pageToBuffer({ page }) { + if (!this.sharp) await this.init(); + try { + this.log(`Converting page ${page.pageNumber} to image...`); + const ops = await page.getOperatorList(); + const pageImages = ops.fnArray.length; + + for (let i = 0; i < pageImages; i++) { + try { + if (!this.validOps.includes(ops.fnArray[i])) continue; + + const name = ops.argsArray[i][0]; + const img = await page.objs.get(name); + const { width, height } = img; + const size = img.data.length; + const channels = size / width / height; + const targetDPI = 70; + const targetWidth = Math.floor(width * (targetDPI / 72)); + const targetHeight = Math.floor(height * (targetDPI / 72)); + + const image = this.sharp(img.data, { + raw: { width, height, channels }, + density: targetDPI, + }) + .resize({ + width: targetWidth, + height: targetHeight, + fit: "fill", + }) + .withMetadata({ + density: targetDPI, + resolution: targetDPI, + }) + .png(); + + // For debugging purposes + // await image.toFile(path.resolve(__dirname, `../../storage/`, `pg${page.pageNumber}.png`)); + return await image.toBuffer(); + } catch (error) { + this.log(`Iteration error: ${error.message}`, error.stack); + continue; + } + } + this.log(`No valid images found on page ${page.pageNumber}`); + return null; + } catch (error) { + this.log(`Error: ${error.message}`, error.stack); + return null; + } + } +} + +module.exports = OCRLoader; diff --git a/collector/utils/OCRLoader/validLangs.js b/collector/utils/OCRLoader/validLangs.js new file mode 100644 index 0000000000000000000000000000000000000000..5bc807ade68561fdfa6c7b49fc17f12bc2f21431 --- /dev/null +++ b/collector/utils/OCRLoader/validLangs.js @@ -0,0 +1,155 @@ +/* + +To get the list of valid language codes - do the following: +Open the following URL in your browser: https://tesseract-ocr.github.io/tessdoc/Data-Files-in-different-versions.html + +Check this element is the proper table tbody with all the codes via console: +document.getElementsByTagName('table').item(0).children.item(1) + +Now, copy the following code and paste it into the console: +function parseLangs() { +let langs = {}; + Array.from(document.getElementsByTagName('table').item(0).children.item(1).children).forEach((el) => { + const [codeEl, languageEl, ...rest] = el.children + const code = codeEl.innerText.trim() + const language = languageEl.innerText.trim() + if (!!code && !!language) langs[code] = language + }) + return langs; +} + +now, run the function: +copy(parseLangs()) +*/ + +const VALID_LANGUAGE_CODES = { + afr: "Afrikaans", + amh: "Amharic", + ara: "Arabic", + asm: "Assamese", + aze: "Azerbaijani", + aze_cyrl: "Azerbaijani - Cyrilic", + bel: "Belarusian", + ben: "Bengali", + bod: "Tibetan", + bos: "Bosnian", + bre: "Breton", + bul: "Bulgarian", + cat: "Catalan; Valencian", + ceb: "Cebuano", + ces: "Czech", + chi_sim: "Chinese - Simplified", + chi_tra: "Chinese - Traditional", + chr: "Cherokee", + cos: "Corsican", + cym: "Welsh", + dan: "Danish", + dan_frak: "Danish - Fraktur (contrib)", + deu: "German", + deu_frak: "German - Fraktur (contrib)", + deu_latf: "German (Fraktur Latin)", + dzo: "Dzongkha", + ell: "Greek, Modern (1453-)", + eng: "English", + enm: "English, Middle (1100-1500)", + epo: "Esperanto", + equ: "Math / equation detection module", + est: "Estonian", + eus: "Basque", + fao: "Faroese", + fas: "Persian", + fil: "Filipino (old - Tagalog)", + fin: "Finnish", + fra: "French", + frk: "German - Fraktur (now deu_latf)", + frm: "French, Middle (ca.1400-1600)", + fry: "Western Frisian", + gla: "Scottish Gaelic", + gle: "Irish", + glg: "Galician", + grc: "Greek, Ancient (to 1453) (contrib)", + guj: "Gujarati", + hat: "Haitian; Haitian Creole", + heb: "Hebrew", + hin: "Hindi", + hrv: "Croatian", + hun: "Hungarian", + hye: "Armenian", + iku: "Inuktitut", + ind: "Indonesian", + isl: "Icelandic", + ita: "Italian", + ita_old: "Italian - Old", + jav: "Javanese", + jpn: "Japanese", + kan: "Kannada", + kat: "Georgian", + kat_old: "Georgian - Old", + kaz: "Kazakh", + khm: "Central Khmer", + kir: "Kirghiz; Kyrgyz", + kmr: "Kurmanji (Kurdish - Latin Script)", + kor: "Korean", + kor_vert: "Korean (vertical)", + kur: "Kurdish (Arabic Script)", + lao: "Lao", + lat: "Latin", + lav: "Latvian", + lit: "Lithuanian", + ltz: "Luxembourgish", + mal: "Malayalam", + mar: "Marathi", + mkd: "Macedonian", + mlt: "Maltese", + mon: "Mongolian", + mri: "Maori", + msa: "Malay", + mya: "Burmese", + nep: "Nepali", + nld: "Dutch; Flemish", + nor: "Norwegian", + oci: "Occitan (post 1500)", + ori: "Oriya", + osd: "Orientation and script detection module", + pan: "Panjabi; Punjabi", + pol: "Polish", + por: "Portuguese", + pus: "Pushto; Pashto", + que: "Quechua", + ron: "Romanian; Moldavian; Moldovan", + rus: "Russian", + san: "Sanskrit", + sin: "Sinhala; Sinhalese", + slk: "Slovak", + slk_frak: "Slovak - Fraktur (contrib)", + slv: "Slovenian", + snd: "Sindhi", + spa: "Spanish; Castilian", + spa_old: "Spanish; Castilian - Old", + sqi: "Albanian", + srp: "Serbian", + srp_latn: "Serbian - Latin", + sun: "Sundanese", + swa: "Swahili", + swe: "Swedish", + syr: "Syriac", + tam: "Tamil", + tat: "Tatar", + tel: "Telugu", + tgk: "Tajik", + tgl: "Tagalog (new - Filipino)", + tha: "Thai", + tir: "Tigrinya", + ton: "Tonga", + tur: "Turkish", + uig: "Uighur; Uyghur", + ukr: "Ukrainian", + urd: "Urdu", + uzb: "Uzbek", + uzb_cyrl: "Uzbek - Cyrilic", + vie: "Vietnamese", + yid: "Yiddish", + yor: "Yoruba", +}; + +module.exports.VALID_LANGUAGE_CODES = VALID_LANGUAGE_CODES; diff --git a/collector/utils/WhisperProviders/OpenAiWhisper.js b/collector/utils/WhisperProviders/OpenAiWhisper.js new file mode 100644 index 0000000000000000000000000000000000000000..e2405b6a9b760fbe249e32da5dc28cc370f58be0 --- /dev/null +++ b/collector/utils/WhisperProviders/OpenAiWhisper.js @@ -0,0 +1,49 @@ +const fs = require("fs"); + +class OpenAiWhisper { + constructor({ options }) { + const { OpenAI: OpenAIApi } = require("openai"); + if (!options.openAiKey) throw new Error("No OpenAI API key was set."); + + this.openai = new OpenAIApi({ + apiKey: options.openAiKey, + }); + this.model = "whisper-1"; + this.temperature = 0; + this.#log("Initialized."); + } + + #log(text, ...args) { + console.log(`\x1b[32m[OpenAiWhisper]\x1b[0m ${text}`, ...args); + } + + async processFile(fullFilePath) { + return await this.openai.audio.transcriptions + .create({ + file: fs.createReadStream(fullFilePath), + model: this.model, + temperature: this.temperature, + }) + .then((response) => { + if (!response) { + return { + content: "", + error: "No content was able to be transcribed.", + }; + } + + return { content: response.text, error: null }; + }) + .catch((error) => { + this.#log( + `Could not get any response from openai whisper`, + error.message + ); + return { content: "", error: error.message }; + }); + } +} + +module.exports = { + OpenAiWhisper, +}; diff --git a/collector/utils/WhisperProviders/localWhisper.js b/collector/utils/WhisperProviders/localWhisper.js new file mode 100644 index 0000000000000000000000000000000000000000..c28df7af0d9a8a0caec55586c6395fc0383151ef --- /dev/null +++ b/collector/utils/WhisperProviders/localWhisper.js @@ -0,0 +1,225 @@ +const fs = require("fs"); +const path = require("path"); +const { v4 } = require("uuid"); +const defaultWhisper = "Xenova/whisper-small"; // Model Card: https://huggingface.co/Xenova/whisper-small +const fileSize = { + "Xenova/whisper-small": "250mb", + "Xenova/whisper-large": "1.56GB", +}; + +class LocalWhisper { + constructor({ options }) { + this.model = options?.WhisperModelPref ?? defaultWhisper; + this.fileSize = fileSize[this.model]; + this.cacheDir = path.resolve( + process.env.STORAGE_DIR + ? path.resolve(process.env.STORAGE_DIR, `models`) + : path.resolve(__dirname, `../../../server/storage/models`) + ); + + this.modelPath = path.resolve(this.cacheDir, ...this.model.split("/")); + // Make directory when it does not exist in existing installations + if (!fs.existsSync(this.cacheDir)) + fs.mkdirSync(this.cacheDir, { recursive: true }); + + this.#log("Initialized."); + } + + #log(text, ...args) { + console.log(`\x1b[32m[LocalWhisper]\x1b[0m ${text}`, ...args); + } + + #validateAudioFile(wavFile) { + const sampleRate = wavFile.fmt.sampleRate; + const duration = wavFile.data.samples / sampleRate; + + // Most speech recognition systems expect minimum 8kHz + // But we'll set it lower to be safe + if (sampleRate < 4000) { + // 4kHz minimum + throw new Error( + "Audio file sample rate is too low for accurate transcription. Minimum required is 4kHz." + ); + } + + // Typical audio file duration limits + const MAX_DURATION_SECONDS = 4 * 60 * 60; // 4 hours + if (duration > MAX_DURATION_SECONDS) { + throw new Error("Audio file duration exceeds maximum limit of 4 hours."); + } + + // Check final sample count after upsampling to prevent memory issues + const targetSampleRate = 16000; + const upsampledSamples = duration * targetSampleRate; + const MAX_SAMPLES = 230_400_000; // ~4 hours at 16kHz + + if (upsampledSamples > MAX_SAMPLES) { + throw new Error("Audio file exceeds maximum allowed length."); + } + + return true; + } + + async #convertToWavAudioData(sourcePath) { + try { + let buffer; + const wavefile = require("wavefile"); + const ffmpeg = require("fluent-ffmpeg"); + const outFolder = path.resolve(__dirname, `../../storage/tmp`); + if (!fs.existsSync(outFolder)) + fs.mkdirSync(outFolder, { recursive: true }); + + const fileExtension = path.extname(sourcePath).toLowerCase(); + if (fileExtension !== ".wav") { + this.#log( + `File conversion required! ${fileExtension} file detected - converting to .wav` + ); + const outputFile = path.resolve(outFolder, `${v4()}.wav`); + const convert = new Promise((resolve) => { + ffmpeg(sourcePath) + .toFormat("wav") + .on("error", (error) => { + this.#log(`Conversion Error! ${error.message}`); + resolve(false); + }) + .on("progress", (progress) => + this.#log( + `Conversion Processing! ${progress.targetSize}KB converted` + ) + ) + .on("end", () => { + this.#log(`Conversion Complete! File converted to .wav!`); + resolve(true); + }) + .save(outputFile); + }); + const success = await convert; + if (!success) + throw new Error( + "[Conversion Failed]: Could not convert file to .wav format!" + ); + + const chunks = []; + const stream = fs.createReadStream(outputFile); + for await (let chunk of stream) chunks.push(chunk); + buffer = Buffer.concat(chunks); + fs.rmSync(outputFile); + } else { + const chunks = []; + const stream = fs.createReadStream(sourcePath); + for await (let chunk of stream) chunks.push(chunk); + buffer = Buffer.concat(chunks); + } + + const wavFile = new wavefile.WaveFile(buffer); + try { + this.#validateAudioFile(wavFile); + } catch (error) { + this.#log(`Audio validation failed: ${error.message}`); + throw new Error(`Invalid audio file: ${error.message}`); + } + + wavFile.toBitDepth("32f"); + wavFile.toSampleRate(16000); + + let audioData = wavFile.getSamples(); + if (Array.isArray(audioData)) { + if (audioData.length > 1) { + const SCALING_FACTOR = Math.sqrt(2); + + // Merge channels into first channel to save memory + for (let i = 0; i < audioData[0].length; ++i) { + audioData[0][i] = + (SCALING_FACTOR * (audioData[0][i] + audioData[1][i])) / 2; + } + } + audioData = audioData[0]; + } + + return audioData; + } catch (error) { + console.error(`convertToWavAudioData`, error); + return null; + } + } + + async client() { + if (!fs.existsSync(this.modelPath)) { + this.#log( + `The native whisper model has never been run and will be downloaded right now. Subsequent runs will be faster. (~${this.fileSize})` + ); + } + + try { + // Convert ESM to CommonJS via import so we can load this library. + const pipeline = (...args) => + import("@xenova/transformers").then(({ pipeline }) => { + return pipeline(...args); + }); + return await pipeline("automatic-speech-recognition", this.model, { + cache_dir: this.cacheDir, + ...(!fs.existsSync(this.modelPath) + ? { + // Show download progress if we need to download any files + progress_callback: (data) => { + if (!data.hasOwnProperty("progress")) return; + console.log( + `\x1b[34m[Embedding - Downloading Model Files]\x1b[0m ${ + data.file + } ${~~data?.progress}%` + ); + }, + } + : {}), + }); + } catch (error) { + let errMsg = error.message; + if (errMsg.includes("Could not locate file")) { + errMsg = + "The native whisper model failed to download from the huggingface.co CDN. Your internet connection may be unstable or blocked by Huggingface.co - you will need to download the model manually and place it in the storage/models folder to use local Whisper transcription."; + } + + this.#log( + `Failed to load the native whisper model: ${errMsg}`, + error.stack + ); + throw new Error(errMsg); + } + } + + async processFile(fullFilePath, filename) { + try { + const audioDataPromise = new Promise((resolve) => + this.#convertToWavAudioData(fullFilePath).then((audioData) => + resolve(audioData) + ) + ); + const [audioData, transcriber] = await Promise.all([ + audioDataPromise, + this.client(), + ]); + + if (!audioData) { + this.#log(`Failed to parse content from ${filename}.`); + return { + content: null, + error: `Failed to parse content from ${filename}.`, + }; + } + + this.#log(`Transcribing audio data to text...`); + const { text } = await transcriber(audioData, { + chunk_length_s: 30, + stride_length_s: 5, + }); + + return { content: text, error: null }; + } catch (error) { + return { content: null, error: error.message }; + } + } +} + +module.exports = { + LocalWhisper, +}; diff --git a/collector/utils/comKey/index.js b/collector/utils/comKey/index.js new file mode 100644 index 0000000000000000000000000000000000000000..a2e2f52a09b2e0f2fe819cf4d86978235e8342fe --- /dev/null +++ b/collector/utils/comKey/index.js @@ -0,0 +1,54 @@ +const crypto = require("crypto"); +const fs = require("fs"); +const path = require("path"); +const keyPath = + process.env.NODE_ENV === "development" + ? path.resolve(__dirname, `../../../server/storage/comkey`) + : path.resolve( + process.env.STORAGE_DIR ?? + path.resolve(__dirname, `../../../server/storage`), + `comkey` + ); + +class CommunicationKey { + #pubKeyName = "ipc-pub.pem"; + #storageLoc = keyPath; + + constructor() {} + + log(text, ...args) { + console.log(`\x1b[36m[CommunicationKeyVerify]\x1b[0m ${text}`, ...args); + } + + #readPublicKey() { + return fs.readFileSync(path.resolve(this.#storageLoc, this.#pubKeyName)); + } + + // Given a signed payload from private key from /app/server/ this signature should + // decode to match the textData provided. This class does verification only in collector. + // Note: The textData is typically the JSON stringified body sent to the document processor API. + verify(signature = "", textData = "") { + try { + let data = textData; + if (typeof textData !== "string") data = JSON.stringify(data); + return crypto.verify( + "RSA-SHA256", + Buffer.from(data), + this.#readPublicKey(), + Buffer.from(signature, "hex") + ); + } catch {} + return false; + } + + // Use the rolling public-key to decrypt arbitrary data that was encrypted via the private key on the server side CommunicationKey class + // that we know was done with the same key-pair and the given input is in base64 format already. + // Returns plaintext string of the data that was encrypted. + decrypt(base64String = "") { + return crypto + .publicDecrypt(this.#readPublicKey(), Buffer.from(base64String, "base64")) + .toString(); + } +} + +module.exports = { CommunicationKey }; diff --git a/collector/utils/constants.js b/collector/utils/constants.js new file mode 100644 index 0000000000000000000000000000000000000000..236fc2fc9a145d0e407c34a6d55c94c95b186020 --- /dev/null +++ b/collector/utils/constants.js @@ -0,0 +1,71 @@ +const WATCH_DIRECTORY = require("path").resolve(__dirname, "../hotdir"); + +const ACCEPTED_MIMES = { + "text/plain": [".txt", ".md", ".org", ".adoc", ".rst"], + "text/html": [".html"], + + "application/vnd.openxmlformats-officedocument.wordprocessingml.document": [ + ".docx", + ], + "application/vnd.openxmlformats-officedocument.presentationml.presentation": [ + ".pptx", + ], + + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": [ + ".xlsx", + ], + + "application/vnd.oasis.opendocument.text": [".odt"], + "application/vnd.oasis.opendocument.presentation": [".odp"], + + "application/pdf": [".pdf"], + "application/mbox": [".mbox"], + + "audio/wav": [".wav"], + "audio/mpeg": [".mp3"], + + "video/mp4": [".mp4"], + "video/mpeg": [".mpeg"], + "application/epub+zip": [".epub"], + "image/png": [".png"], + "image/jpeg": [".jpg"], + "image/jpg": [".jpg"], +}; + +const SUPPORTED_FILETYPE_CONVERTERS = { + ".txt": "./convert/asTxt.js", + ".md": "./convert/asTxt.js", + ".org": "./convert/asTxt.js", + ".adoc": "./convert/asTxt.js", + ".rst": "./convert/asTxt.js", + + ".html": "./convert/asTxt.js", + ".pdf": "./convert/asPDF/index.js", + + ".docx": "./convert/asDocx.js", + ".pptx": "./convert/asOfficeMime.js", + + ".odt": "./convert/asOfficeMime.js", + ".odp": "./convert/asOfficeMime.js", + + ".xlsx": "./convert/asXlsx.js", + + ".mbox": "./convert/asMbox.js", + + ".epub": "./convert/asEPub.js", + + ".mp3": "./convert/asAudio.js", + ".wav": "./convert/asAudio.js", + ".mp4": "./convert/asAudio.js", + ".mpeg": "./convert/asAudio.js", + + ".png": "./convert/asImage.js", + ".jpg": "./convert/asImage.js", + ".jpeg": "./convert/asImage.js", +}; + +module.exports = { + SUPPORTED_FILETYPE_CONVERTERS, + WATCH_DIRECTORY, + ACCEPTED_MIMES, +}; diff --git a/collector/utils/extensions/Confluence/ConfluenceLoader/index.js b/collector/utils/extensions/Confluence/ConfluenceLoader/index.js new file mode 100644 index 0000000000000000000000000000000000000000..d84a64fbeab0a54d6c4b40736fc6524b714ae9d0 --- /dev/null +++ b/collector/utils/extensions/Confluence/ConfluenceLoader/index.js @@ -0,0 +1,141 @@ +/* + * This is a custom implementation of the Confluence langchain loader. There was an issue where + * code blocks were not being extracted. This is a temporary fix until this issue is resolved.*/ + +const { htmlToText } = require("html-to-text"); + +class ConfluencePagesLoader { + constructor({ + baseUrl, + spaceKey, + username, + accessToken, + limit = 25, + expand = "body.storage,version", + personalAccessToken, + cloud = true, + }) { + this.baseUrl = baseUrl; + this.spaceKey = spaceKey; + this.username = username; + this.accessToken = accessToken; + this.limit = limit; + this.expand = expand; + this.personalAccessToken = personalAccessToken; + this.cloud = cloud; + } + + get authorizationHeader() { + if (this.personalAccessToken) { + return `Bearer ${this.personalAccessToken}`; + } else if (this.username && this.accessToken) { + const authToken = Buffer.from( + `${this.username}:${this.accessToken}` + ).toString("base64"); + return `Basic ${authToken}`; + } + return undefined; + } + + async load(options) { + try { + const pages = await this.fetchAllPagesInSpace( + options?.start, + options?.limit + ); + return pages.map((page) => this.createDocumentFromPage(page)); + } catch (error) { + console.error("Error:", error); + return []; + } + } + + async fetchConfluenceData(url) { + try { + const initialHeaders = { + "Content-Type": "application/json", + Accept: "application/json", + }; + const authHeader = this.authorizationHeader; + if (authHeader) { + initialHeaders.Authorization = authHeader; + } + const response = await fetch(url, { + headers: initialHeaders, + }); + if (!response.ok) { + throw new Error( + `Failed to fetch ${url} from Confluence: ${response.status}` + ); + } + return await response.json(); + } catch (error) { + throw new Error(`Failed to fetch ${url} from Confluence: ${error}`); + } + } + + // https://developer.atlassian.com/cloud/confluence/rest/v2/intro/#auth + async fetchAllPagesInSpace(start = 0, limit = this.limit) { + const url = `${this.baseUrl}${ + this.cloud ? "/wiki" : "" + }/rest/api/content?spaceKey=${ + this.spaceKey + }&limit=${limit}&start=${start}&expand=${this.expand}`; + const data = await this.fetchConfluenceData(url); + if (data.size === 0) { + return []; + } + const nextPageStart = start + data.size; + const nextPageResults = await this.fetchAllPagesInSpace( + nextPageStart, + limit + ); + return data.results.concat(nextPageResults); + } + + createDocumentFromPage(page) { + // Function to extract code blocks + const extractCodeBlocks = (content) => { + const codeBlockRegex = + /]*>[\s\S]*?<\/ac:plain-text-body>[\s\S]*?<\/ac:structured-macro>/g; + const languageRegex = + /(.*?)<\/ac:parameter>/; + + return content.replace(codeBlockRegex, (match) => { + const language = match.match(languageRegex)?.[1] || ""; + const code = + match.match( + /<\/ac:plain-text-body>/ + )?.[1] || ""; + return `\n\`\`\`${language}\n${code.trim()}\n\`\`\`\n`; + }); + }; + + const contentWithCodeBlocks = extractCodeBlocks(page.body.storage.value); + const plainTextContent = htmlToText(contentWithCodeBlocks, { + wordwrap: false, + preserveNewlines: true, + }); + const textWithPreservedStructure = plainTextContent.replace( + /\n{3,}/g, + "\n\n" + ); + const pageUrl = `${this.baseUrl}/spaces/${this.spaceKey}/pages/${page.id}`; + + return { + pageContent: textWithPreservedStructure, + metadata: { + id: page.id, + status: page.status, + title: page.title, + type: page.type, + url: pageUrl, + version: page.version?.number, + updated_by: page.version?.by?.displayName, + updated_at: page.version?.when, + }, + }; + } +} + +module.exports = { ConfluencePagesLoader }; diff --git a/collector/utils/extensions/Confluence/index.js b/collector/utils/extensions/Confluence/index.js new file mode 100644 index 0000000000000000000000000000000000000000..7e31077799eeb8a5ee6082c697ee5d5226efaf51 --- /dev/null +++ b/collector/utils/extensions/Confluence/index.js @@ -0,0 +1,261 @@ +const fs = require("fs"); +const path = require("path"); +const { default: slugify } = require("slugify"); +const { v4 } = require("uuid"); +const { writeToServerDocuments, sanitizeFileName } = require("../../files"); +const { tokenizeString } = require("../../tokenizer"); +const { ConfluencePagesLoader } = require("./ConfluenceLoader"); + +/** + * Load Confluence documents from a spaceID and Confluence credentials + * @param {object} args - forwarded request body params + * @param {import("../../../middleware/setDataSigner").ResponseWithSigner} response - Express response object with encryptionWorker + * @returns + */ +async function loadConfluence( + { + baseUrl = null, + spaceKey = null, + username = null, + accessToken = null, + cloud = true, + personalAccessToken = null, + }, + response +) { + if (!personalAccessToken && (!username || !accessToken)) { + return { + success: false, + reason: + "You need either a personal access token (PAT), or a username and access token to use the Confluence connector.", + }; + } + + if (!baseUrl || !validBaseUrl(baseUrl)) { + return { + success: false, + reason: "Provided base URL is not a valid URL.", + }; + } + + if (!spaceKey) { + return { + success: false, + reason: "You need to provide a Confluence space key.", + }; + } + + const { origin, hostname } = new URL(baseUrl); + console.log(`-- Working Confluence ${origin} --`); + const loader = new ConfluencePagesLoader({ + baseUrl: origin, // Use the origin to avoid issues with subdomains, ports, protocols, etc. + spaceKey, + username, + accessToken, + cloud, + personalAccessToken, + }); + + const { docs, error } = await loader + .load() + .then((docs) => { + return { docs, error: null }; + }) + .catch((e) => { + return { + docs: [], + error: e.message?.split("Error:")?.[1] || e.message, + }; + }); + + if (!docs.length || !!error) { + return { + success: false, + reason: error ?? "No pages found for that Confluence space.", + }; + } + const outFolder = slugify( + `confluence-${hostname}-${v4().slice(0, 4)}` + ).toLowerCase(); + + const outFolderPath = + process.env.NODE_ENV === "development" + ? path.resolve( + __dirname, + `../../../../server/storage/documents/${outFolder}` + ) + : path.resolve(process.env.STORAGE_DIR, `documents/${outFolder}`); + + if (!fs.existsSync(outFolderPath)) + fs.mkdirSync(outFolderPath, { recursive: true }); + + docs.forEach((doc) => { + if (!doc.pageContent) return; + + const data = { + id: v4(), + url: doc.metadata.url + ".page", + title: doc.metadata.title || doc.metadata.source, + docAuthor: origin, + description: doc.metadata.title, + docSource: `${origin} Confluence`, + chunkSource: generateChunkSource( + { doc, baseUrl: origin, spaceKey, accessToken, username, cloud }, + response.locals.encryptionWorker + ), + published: new Date().toLocaleString(), + wordCount: doc.pageContent.split(" ").length, + pageContent: doc.pageContent, + token_count_estimate: tokenizeString(doc.pageContent), + }; + + console.log( + `[Confluence Loader]: Saving ${doc.metadata.title} to ${outFolder}` + ); + + const fileName = sanitizeFileName( + `${slugify(doc.metadata.title)}-${data.id}` + ); + writeToServerDocuments({ + data, + filename: fileName, + destinationOverride: outFolderPath, + }); + }); + + return { + success: true, + reason: null, + data: { + spaceKey, + destination: outFolder, + }, + }; +} + +/** + * Gets the page content from a specific Confluence page, not all pages in a workspace. + * @returns + */ +async function fetchConfluencePage({ + pageUrl, + baseUrl, + spaceKey, + username, + accessToken, + cloud = true, +}) { + if (!pageUrl || !baseUrl || !spaceKey || !username || !accessToken) { + return { + success: false, + content: null, + reason: + "You need either a username and access token, or a personal access token (PAT), to use the Confluence connector.", + }; + } + + if (!validBaseUrl(baseUrl)) { + return { + success: false, + content: null, + reason: "Provided base URL is not a valid URL.", + }; + } + + if (!spaceKey) { + return { + success: false, + content: null, + reason: "You need to provide a Confluence space key.", + }; + } + + console.log(`-- Working Confluence Page ${pageUrl} --`); + const loader = new ConfluencePagesLoader({ + baseUrl, // Should be the origin of the baseUrl + spaceKey, + username, + accessToken, + cloud, + }); + + const { docs, error } = await loader + .load() + .then((docs) => { + return { docs, error: null }; + }) + .catch((e) => { + return { + docs: [], + error: e.message?.split("Error:")?.[1] || e.message, + }; + }); + + if (!docs.length || !!error) { + return { + success: false, + reason: error ?? "No pages found for that Confluence space.", + content: null, + }; + } + + const targetDocument = docs.find( + (doc) => doc.pageContent && doc.metadata.url === pageUrl + ); + if (!targetDocument) { + return { + success: false, + reason: "Target page could not be found in Confluence space.", + content: null, + }; + } + + return { + success: true, + reason: null, + content: targetDocument.pageContent, + }; +} + +/** + * Validates if the provided baseUrl is a valid URL at all. + * @param {string} baseUrl + * @returns {boolean} + */ +function validBaseUrl(baseUrl) { + try { + new URL(baseUrl); + return true; + } catch (e) { + return false; + } +} + +/** + * Generate the full chunkSource for a specific Confluence page so that we can resync it later. + * This data is encrypted into a single `payload` query param so we can replay credentials later + * since this was encrypted with the systems persistent password and salt. + * @param {object} chunkSourceInformation + * @param {import("../../EncryptionWorker").EncryptionWorker} encryptionWorker + * @returns {string} + */ +function generateChunkSource( + { doc, baseUrl, spaceKey, accessToken, username, cloud }, + encryptionWorker +) { + const payload = { + baseUrl, + spaceKey, + token: accessToken, + username, + cloud, + }; + return `confluence://${doc.metadata.url}?payload=${encryptionWorker.encrypt( + JSON.stringify(payload) + )}`; +} + +module.exports = { + loadConfluence, + fetchConfluencePage, +}; diff --git a/collector/utils/extensions/DrupalWiki/DrupalWiki/index.js b/collector/utils/extensions/DrupalWiki/DrupalWiki/index.js new file mode 100644 index 0000000000000000000000000000000000000000..9ca6259336d54d23ddc533edaa7bb11b213d306e --- /dev/null +++ b/collector/utils/extensions/DrupalWiki/DrupalWiki/index.js @@ -0,0 +1,326 @@ +/** + * Copyright 2024 + * + * Authors: + * - Eugen Mayer (KontextWork) + */ + +const { htmlToText } = require("html-to-text"); +const { tokenizeString } = require("../../../tokenizer"); +const { + sanitizeFileName, + writeToServerDocuments, + documentsFolder, +} = require("../../../files"); +const { default: slugify } = require("slugify"); +const path = require("path"); +const fs = require("fs"); +const { processSingleFile } = require("../../../../processSingleFile"); +const { + WATCH_DIRECTORY, + SUPPORTED_FILETYPE_CONVERTERS, +} = require("../../../constants"); + +class Page { + /** + * + * @param {number }id + * @param {string }title + * @param {string} created + * @param {string} type + * @param {string} processedBody + * @param {string} url + * @param {number} spaceId + */ + constructor({ id, title, created, type, processedBody, url, spaceId }) { + this.id = id; + this.title = title; + this.url = url; + this.created = created; + this.type = type; + this.processedBody = processedBody; + this.spaceId = spaceId; + } +} + +class DrupalWiki { + /** + * + * @param baseUrl + * @param spaceId + * @param accessToken + */ + constructor({ baseUrl, accessToken }) { + this.baseUrl = baseUrl; + this.accessToken = accessToken; + this.storagePath = this.#prepareStoragePath(baseUrl); + } + + /** + * Load all pages for the given space, fetching storing each page one by one + * to minimize the memory usage + * + * @param {number} spaceId + * @param {import("../../EncryptionWorker").EncryptionWorker} encryptionWorker + * @returns {Promise} + */ + async loadAndStoreAllPagesForSpace(spaceId, encryptionWorker) { + const pageIndex = await this.#getPageIndexForSpace(spaceId); + for (const pageId of pageIndex) { + try { + const page = await this.loadPage(pageId); + + // Pages with an empty body will lead to embedding issues / exceptions + if (page.processedBody.trim() !== "") { + this.#storePage(page, encryptionWorker); + await this.#downloadAndProcessAttachments(page.id); + } else { + console.log(`Skipping page (${page.id}) since it has no content`); + } + } catch (e) { + console.error( + `Could not process DrupalWiki page ${pageId} (skipping and continuing): ` + ); + console.error(e); + } + } + } + + /** + * @param {number} pageId + * @returns {Promise} + */ + async loadPage(pageId) { + return this.#fetchPage(pageId); + } + + /** + * Fetches the page ids for the configured space + * @param {number} spaceId + * @returns{Promise} array of pageIds + */ + async #getPageIndexForSpace(spaceId) { + // errors on fetching the pageIndex is fatal, no error handling + let hasNext = true; + let pageIds = []; + let pageNr = 0; + do { + let { isLast, pageIdsForPage } = await this.#getPagesForSpacePaginated( + spaceId, + pageNr + ); + hasNext = !isLast; + pageNr++; + if (pageIdsForPage.length) { + pageIds = pageIds.concat(pageIdsForPage); + } + } while (hasNext); + + return pageIds; + } + + /** + * + * @param {number} pageNr + * @param {number} spaceId + * @returns {Promise<{isLast,pageIds}>} + */ + async #getPagesForSpacePaginated(spaceId, pageNr) { + /* + * { + * content: Page[], + * last: boolean, + * pageable: { + * pageNumber: number + * } + * } + */ + const data = await this._doFetch( + `${this.baseUrl}/api/rest/scope/api/page?size=100&space=${spaceId}&page=${pageNr}` + ); + + const pageIds = data.content.map((page) => { + return Number(page.id); + }); + + return { + isLast: data.last, + pageIdsForPage: pageIds, + }; + } + + /** + * @param pageId + * @returns {Promise} + */ + async #fetchPage(pageId) { + const data = await this._doFetch( + `${this.baseUrl}/api/rest/scope/api/page/${pageId}` + ); + const url = `${this.baseUrl}/node/${data.id}`; + return new Page({ + id: data.id, + title: data.title, + created: data.lastModified, + type: data.type, + processedBody: this.#processPageBody({ + body: data.body, + title: data.title, + lastModified: data.lastModified, + url: url, + }), + url: url, + }); + } + + /** + * @param {Page} page + * @param {import("../../EncryptionWorker").EncryptionWorker} encryptionWorker + */ + #storePage(page, encryptionWorker) { + const { hostname } = new URL(this.baseUrl); + + // This UUID will ensure that re-importing the same page without any changes will not + // show up (deduplication). + const targetUUID = `${hostname}.${page.spaceId}.${page.id}.${page.created}`; + const wordCount = page.processedBody.split(" ").length; + const data = { + id: targetUUID, + url: `drupalwiki://${page.url}`, + title: page.title, + docAuthor: this.baseUrl, + description: page.title, + docSource: `${this.baseUrl} DrupalWiki`, + chunkSource: this.#generateChunkSource(page.id, encryptionWorker), + published: new Date().toLocaleString(), + wordCount: wordCount, + pageContent: page.processedBody, + token_count_estimate: tokenizeString(page.processedBody), + }; + + const fileName = sanitizeFileName(`${slugify(page.title)}-${data.id}`); + console.log( + `[DrupalWiki Loader]: Saving page '${page.title}' (${page.id}) to '${this.storagePath}/${fileName}'` + ); + writeToServerDocuments({ + data, + filename: fileName, + destinationOverride: this.storagePath, + }); + } + + /** + * Generate the full chunkSource for a specific Confluence page so that we can resync it later. + * This data is encrypted into a single `payload` query param so we can replay credentials later + * since this was encrypted with the systems persistent password and salt. + * @param {number} pageId + * @param {import("../../EncryptionWorker").EncryptionWorker} encryptionWorker + * @returns {string} + */ + #generateChunkSource(pageId, encryptionWorker) { + const payload = { + baseUrl: this.baseUrl, + pageId: pageId, + accessToken: this.accessToken, + }; + return `drupalwiki://${ + this.baseUrl + }/node/${pageId}?payload=${encryptionWorker.encrypt( + JSON.stringify(payload) + )}`; + } + + async _doFetch(url) { + const response = await fetch(url, { + headers: this.#getHeaders(), + }); + if (!response.ok) { + throw new Error(`Failed to fetch ${url}: ${response.status}`); + } + return response.json(); + } + + #getHeaders() { + return { + "Content-Type": "application/json", + Accept: "application/json", + Authorization: `Bearer ${this.accessToken}`, + }; + } + + #prepareStoragePath(baseUrl) { + const { hostname } = new URL(baseUrl); + const subFolder = slugify(`drupalwiki-${hostname}`).toLowerCase(); + const outFolder = path.resolve(documentsFolder, subFolder); + if (!fs.existsSync(outFolder)) fs.mkdirSync(outFolder, { recursive: true }); + return outFolder; + } + + /** + * @param {string} body + * @param {string} url + * @param {string} title + * @param {string} lastModified + * @returns {string} + * @private + */ + #processPageBody({ body, url, title, lastModified }) { + const textContent = body.trim() !== "" ? body : title; + + const plainTextContent = htmlToText(textContent, { + wordwrap: false, + preserveNewlines: true, + selectors: [ + { + selector: "table", + format: "dataTable", + options: { + colSpacing: 3, + rowSpacing: 1, + uppercaseHeaderCells: true, + maxColumnWidth: Infinity, + }, + }, + ], + }); + + const plainBody = plainTextContent.replace(/\n{3,}/g, "\n\n"); + return plainBody; + } + + async #downloadAndProcessAttachments(pageId) { + try { + const data = await this._doFetch( + `${this.baseUrl}/api/rest/scope/api/attachment?pageId=${pageId}&size=2000` + ); + + const extensionsList = Object.keys(SUPPORTED_FILETYPE_CONVERTERS); + for (const attachment of data.content || data) { + const { fileName, id: attachId } = attachment; + const lowerName = fileName.toLowerCase(); + if (!extensionsList.some((ext) => lowerName.endsWith(ext))) { + continue; + } + + const downloadUrl = `${this.baseUrl}/api/rest/scope/api/attachment/${attachId}/download`; + const attachmentResponse = await fetch(downloadUrl, { + headers: this.#getHeaders(), + }); + if (!attachmentResponse.ok) { + console.log(`Skipping attachment: ${fileName} - Download failed`); + continue; + } + + const buffer = await attachmentResponse.arrayBuffer(); + const localFilePath = `${WATCH_DIRECTORY}/${fileName}`; + require("fs").writeFileSync(localFilePath, Buffer.from(buffer)); + + await processSingleFile(fileName); + } + } catch (err) { + console.error(`Fetching/processing attachments failed:`, err); + } + } +} + +module.exports = { DrupalWiki }; diff --git a/collector/utils/extensions/DrupalWiki/index.js b/collector/utils/extensions/DrupalWiki/index.js new file mode 100644 index 0000000000000000000000000000000000000000..81be6f3627820fc7ff61fcc79db509bc2dfbb882 --- /dev/null +++ b/collector/utils/extensions/DrupalWiki/index.js @@ -0,0 +1,102 @@ +/** + * Copyright 2024 + * + * Authors: + * - Eugen Mayer (KontextWork) + */ + +const { DrupalWiki } = require("./DrupalWiki"); +const { validBaseUrl } = require("../../../utils/http"); + +async function loadAndStoreSpaces( + { baseUrl = null, spaceIds = null, accessToken = null }, + response +) { + if (!baseUrl) { + return { + success: false, + reason: + "Please provide your baseUrl like https://mywiki.drupal-wiki.net.", + }; + } else if (!validBaseUrl(baseUrl)) { + return { + success: false, + reason: "Provided base URL is not a valid URL.", + }; + } + + if (!spaceIds) { + return { + success: false, + reason: + "Please provide a list of spaceIds like 21,56,67 you want to extract", + }; + } + + if (!accessToken) { + return { + success: false, + reason: "Please provide a REST API-Token.", + }; + } + + console.log(`-- Working Drupal Wiki ${baseUrl} for spaceIds: ${spaceIds} --`); + const drupalWiki = new DrupalWiki({ baseUrl, accessToken }); + + const encryptionWorker = response.locals.encryptionWorker; + const spaceIdsArr = spaceIds.split(",").map((idStr) => { + return Number(idStr.trim()); + }); + + for (const spaceId of spaceIdsArr) { + try { + await drupalWiki.loadAndStoreAllPagesForSpace(spaceId, encryptionWorker); + console.log(`--- Finished space ${spaceId} ---`); + } catch (e) { + console.error(e); + return { + success: false, + reason: e.message, + data: {}, + }; + } + } + console.log(`-- Finished all spaces--`); + + return { + success: true, + reason: null, + data: { + spaceIds, + destination: drupalWiki.storagePath, + }, + }; +} + +/** + * Gets the page content from a specific Confluence page, not all pages in a workspace. + * @returns + */ +async function loadPage({ baseUrl, pageId, accessToken }) { + console.log(`-- Working Drupal Wiki Page ${pageId} of ${baseUrl} --`); + const drupalWiki = new DrupalWiki({ baseUrl, accessToken }); + try { + const page = await drupalWiki.loadPage(pageId); + return { + success: true, + reason: null, + content: page.processedBody, + }; + } catch (e) { + return { + success: false, + reason: `Failed (re)-fetching DrupalWiki page ${pageId} form ${baseUrl}}`, + content: null, + }; + } +} + +module.exports = { + loadAndStoreSpaces, + loadPage, +}; diff --git a/collector/utils/extensions/ObsidianVault/index.js b/collector/utils/extensions/ObsidianVault/index.js new file mode 100644 index 0000000000000000000000000000000000000000..52d4bbb8e0653364ca627510941f1faec9d625c6 --- /dev/null +++ b/collector/utils/extensions/ObsidianVault/index.js @@ -0,0 +1,95 @@ +const { v4 } = require("uuid"); +const { default: slugify } = require("slugify"); +const path = require("path"); +const fs = require("fs"); +const { + writeToServerDocuments, + sanitizeFileName, + documentsFolder, +} = require("../../files"); + +function parseObsidianVaultPath(files = []) { + const possiblePaths = new Set(); + files.forEach( + (file) => file?.path && possiblePaths.add(file.path.split("/")[0]) + ); + + switch (possiblePaths.size) { + case 0: + return null; + case 1: + // The user specified a vault properly - so all files are in the same folder. + return possiblePaths.values().next().value; + default: + return null; + } +} + +async function loadObsidianVault({ files = [] }) { + if (!files || files?.length === 0) + return { success: false, error: "No files provided" }; + const vaultName = parseObsidianVaultPath(files); + const folderUUId = v4().slice(0, 4); + const outFolder = vaultName + ? slugify(`obsidian-vault-${vaultName}-${folderUUId}`).toLowerCase() + : slugify(`obsidian-${folderUUId}`).toLowerCase(); + const outFolderPath = path.resolve(documentsFolder, outFolder); + if (!fs.existsSync(outFolderPath)) + fs.mkdirSync(outFolderPath, { recursive: true }); + + console.log( + `Processing ${files.length} files from Obsidian Vault ${ + vaultName ? `"${vaultName}"` : "" + }` + ); + const results = []; + for (const file of files) { + try { + const fullPageContent = file?.content; + // If the file has no content or is just whitespace, skip it. + if (!fullPageContent || fullPageContent.trim() === "") continue; + + const data = { + id: v4(), + url: `obsidian://${file.path}`, + title: file.name, + docAuthor: "Obsidian Vault", + description: file.name, + docSource: "Obsidian Vault", + chunkSource: `obsidian://${file.path}`, + published: new Date().toLocaleString(), + wordCount: fullPageContent.split(" ").length, + pageContent: fullPageContent, + token_count_estimate: fullPageContent.length / 4, // rough estimate + }; + + const targetFileName = sanitizeFileName( + `${slugify(file.name)}-${data.id}` + ); + writeToServerDocuments({ + data, + filename: targetFileName, + destinationOverride: outFolderPath, + }); + results.push({ file: file.path, status: "success" }); + } catch (e) { + console.error(`Failed to process ${file.path}:`, e); + results.push({ file: file.path, status: "failed", reason: e.message }); + } + } + + return { + success: true, + data: { + processed: results.filter((r) => r.status === "success").length, + failed: results.filter((r) => r.status === "failed").length, + total: files.length, + results, + destination: path.basename(outFolderPath), + }, + }; +} + +module.exports = { + loadObsidianVault, +}; diff --git a/collector/utils/extensions/RepoLoader/GithubRepo/RepoLoader/index.js b/collector/utils/extensions/RepoLoader/GithubRepo/RepoLoader/index.js new file mode 100644 index 0000000000000000000000000000000000000000..58807517f09e8db1e0c7fa8ea5b0a799dfd03eee --- /dev/null +++ b/collector/utils/extensions/RepoLoader/GithubRepo/RepoLoader/index.js @@ -0,0 +1,265 @@ +/** + * @typedef {Object} RepoLoaderArgs + * @property {string} repo - The GitHub repository URL. + * @property {string} [branch] - The branch to load from (optional). + * @property {string} [accessToken] - GitHub access token for authentication (optional). + * @property {string[]} [ignorePaths] - Array of paths to ignore when loading (optional). + */ + +/** + * @class + * @classdesc Loads and manages GitHub repository content. + */ +class GitHubRepoLoader { + /** + * Creates an instance of RepoLoader. + * @param {RepoLoaderArgs} [args] - The configuration options. + * @returns {GitHubRepoLoader} + */ + constructor(args = {}) { + this.ready = false; + this.repo = this.#processRepoUrl(args?.repo); + this.branch = args?.branch; + this.accessToken = args?.accessToken || null; + this.ignorePaths = args?.ignorePaths || []; + + this.author = null; + this.project = null; + this.branches = []; + } + + /** + * Processes a repository URL to ensure it is in the correct format + * - remove the .git suffix if present + * - ensure the url is valid + * @param {string} repoUrl - The repository URL to process. + * @returns {string|null} The processed repository URL, or null if the URL is invalid. + */ + #processRepoUrl(repoUrl) { + if (!repoUrl) return repoUrl; + try { + const url = new URL(repoUrl); + if (url.pathname.endsWith(".git")) + url.pathname = url.pathname.slice(0, -4); + return url.toString(); + } catch (e) { + console.error( + `[GitHub Loader]: Error processing repository URL ${this.repo}: ${e.message}` + ); + return repoUrl; + } + } + + /** + * Validates the GitHub URL format. + * - ensure the url is valid + * - ensure the hostname is github.com + * - ensure the pathname is in the format of github.com/{author}/{project} + * - sets the author and project properties of class instance + * @returns {boolean} True if the URL is valid, false otherwise. + */ + #validGithubUrl() { + try { + const url = new URL(this.repo); + + // Not a github url at all. + if (url.hostname !== "github.com") { + console.log( + `[GitHub Loader]: Invalid GitHub URL provided! Hostname must be 'github.com'. Got ${url.hostname}` + ); + return false; + } + + // Assume the url is in the format of github.com/{author}/{project} + // Remove the first slash from the pathname so we can split it properly. + const [author, project, ..._rest] = url.pathname.slice(1).split("/"); + if (!author || !project) { + console.log( + `[GitHub Loader]: Invalid GitHub URL provided! URL must be in the format of 'github.com/{author}/{project}'. Got ${url.pathname}` + ); + return false; + } + + this.author = author; + this.project = project; + return true; + } catch (e) { + console.log( + `[GitHub Loader]: Invalid GitHub URL provided! Error: ${e.message}` + ); + return false; + } + } + + // Ensure the branch provided actually exists + // and if it does not or has not been set auto-assign to primary branch. + async #validBranch() { + await this.getRepoBranches(); + if (!!this.branch && this.branches.includes(this.branch)) return; + + console.log( + "[GitHub Loader]: Branch not set! Auto-assigning to a default branch." + ); + this.branch = this.branches.includes("main") ? "main" : "master"; + console.log(`[GitHub Loader]: Branch auto-assigned to ${this.branch}.`); + return; + } + + async #validateAccessToken() { + if (!this.accessToken) return; + const valid = await fetch("https://api.github.com/octocat", { + method: "GET", + headers: { + Authorization: `Bearer ${this.accessToken}`, + "X-GitHub-Api-Version": "2022-11-28", + }, + }) + .then((res) => { + if (!res.ok) throw new Error(res.statusText); + return res.ok; + }) + .catch((e) => { + console.error( + "Invalid GitHub Access Token provided! Access token will not be used", + e.message + ); + return false; + }); + + if (!valid) this.accessToken = null; + return; + } + + /** + * Initializes the RepoLoader instance. + * @returns {Promise} The initialized RepoLoader instance. + */ + async init() { + if (!this.#validGithubUrl()) return; + await this.#validBranch(); + await this.#validateAccessToken(); + this.ready = true; + return this; + } + + /** + * Recursively loads the repository content. + * @returns {Promise>} An array of loaded documents. + * @throws {Error} If the RepoLoader is not in a ready state. + */ + async recursiveLoader() { + if (!this.ready) throw new Error("[GitHub Loader]: not in ready state!"); + const { + GithubRepoLoader: LCGithubLoader, + } = require("@langchain/community/document_loaders/web/github"); + + if (this.accessToken) + console.log( + `[GitHub Loader]: Access token set! Recursive loading enabled!` + ); + + const loader = new LCGithubLoader(this.repo, { + branch: this.branch, + recursive: !!this.accessToken, // Recursive will hit rate limits. + maxConcurrency: 5, + unknown: "warn", + accessToken: this.accessToken, + ignorePaths: this.ignorePaths, + verbose: true, + }); + + const docs = await loader.load(); + return docs; + } + + // Sort branches to always show either main or master at the top of the result. + #branchPrefSort(branches = []) { + const preferredSort = ["main", "master"]; + return branches.reduce((acc, branch) => { + if (preferredSort.includes(branch)) return [branch, ...acc]; + return [...acc, branch]; + }, []); + } + + /** + * Retrieves all branches for the repository. + * @returns {Promise} An array of branch names. + */ + async getRepoBranches() { + if (!this.#validGithubUrl() || !this.author || !this.project) return []; + await this.#validateAccessToken(); // Ensure API access token is valid for pre-flight + + let page = 0; + let polling = true; + const branches = []; + + while (polling) { + console.log(`Fetching page ${page} of branches for ${this.project}`); + await fetch( + `https://api.github.com/repos/${this.author}/${this.project}/branches?per_page=100&page=${page}`, + { + method: "GET", + headers: { + ...(this.accessToken + ? { Authorization: `Bearer ${this.accessToken}` } + : {}), + "X-GitHub-Api-Version": "2022-11-28", + }, + } + ) + .then((res) => { + if (res.ok) return res.json(); + throw new Error(`Invalid request to Github API: ${res.statusText}`); + }) + .then((branchObjects) => { + polling = branchObjects.length > 0; + branches.push(branchObjects.map((branch) => branch.name)); + page++; + }) + .catch((err) => { + polling = false; + console.log(`RepoLoader.branches`, err); + }); + } + + this.branches = [...new Set(branches.flat())]; + return this.#branchPrefSort(this.branches); + } + + /** + * Fetches the content of a single file from the repository. + * @param {string} sourceFilePath - The path to the file in the repository. + * @returns {Promise} The content of the file, or null if fetching fails. + */ + async fetchSingleFile(sourceFilePath) { + try { + return fetch( + `https://api.github.com/repos/${this.author}/${this.project}/contents/${sourceFilePath}?ref=${this.branch}`, + { + method: "GET", + headers: { + Accept: "application/vnd.github+json", + "X-GitHub-Api-Version": "2022-11-28", + ...(!!this.accessToken + ? { Authorization: `Bearer ${this.accessToken}` } + : {}), + }, + } + ) + .then((res) => { + if (res.ok) return res.json(); + throw new Error(`Failed to fetch from Github API: ${res.statusText}`); + }) + .then((json) => { + if (json.hasOwnProperty("status") || !json.hasOwnProperty("content")) + throw new Error(json?.message || "missing content"); + return atob(json.content); + }); + } catch (e) { + console.error(`RepoLoader.fetchSingleFile`, e); + return null; + } + } +} + +module.exports = GitHubRepoLoader; diff --git a/collector/utils/extensions/RepoLoader/GithubRepo/index.js b/collector/utils/extensions/RepoLoader/GithubRepo/index.js new file mode 100644 index 0000000000000000000000000000000000000000..fae6ef491c4aa59c1f29222c2e8cf7acfd929302 --- /dev/null +++ b/collector/utils/extensions/RepoLoader/GithubRepo/index.js @@ -0,0 +1,159 @@ +const RepoLoader = require("./RepoLoader"); +const fs = require("fs"); +const path = require("path"); +const { default: slugify } = require("slugify"); +const { v4 } = require("uuid"); +const { writeToServerDocuments } = require("../../../files"); +const { tokenizeString } = require("../../../tokenizer"); + +/** + * Load in a GitHub Repo recursively or just the top level if no PAT is provided + * @param {object} args - forwarded request body params + * @param {import("../../../middleware/setDataSigner").ResponseWithSigner} response - Express response object with encryptionWorker + * @returns + */ +async function loadGithubRepo(args, response) { + const repo = new RepoLoader(args); + await repo.init(); + + if (!repo.ready) + return { + success: false, + reason: "Could not prepare GitHub repo for loading! Check URL", + }; + + console.log( + `-- Working GitHub ${repo.author}/${repo.project}:${repo.branch} --` + ); + const docs = await repo.recursiveLoader(); + if (!docs.length) { + return { + success: false, + reason: "No files were found for those settings.", + }; + } + + console.log(`[GitHub Loader]: Found ${docs.length} source files. Saving...`); + const outFolder = slugify( + `${repo.author}-${repo.project}-${repo.branch}-${v4().slice(0, 4)}` + ).toLowerCase(); + + const outFolderPath = + process.env.NODE_ENV === "development" + ? path.resolve( + __dirname, + `../../../../../server/storage/documents/${outFolder}` + ) + : path.resolve(process.env.STORAGE_DIR, `documents/${outFolder}`); + + if (!fs.existsSync(outFolderPath)) + fs.mkdirSync(outFolderPath, { recursive: true }); + + for (const doc of docs) { + if (!doc.pageContent) continue; + const data = { + id: v4(), + url: "github://" + doc.metadata.source, + title: doc.metadata.source, + docAuthor: repo.author, + description: "No description found.", + docSource: doc.metadata.source, + chunkSource: generateChunkSource( + repo, + doc, + response.locals.encryptionWorker + ), + published: new Date().toLocaleString(), + wordCount: doc.pageContent.split(" ").length, + pageContent: doc.pageContent, + token_count_estimate: tokenizeString(doc.pageContent), + }; + console.log( + `[GitHub Loader]: Saving ${doc.metadata.source} to ${outFolder}` + ); + writeToServerDocuments({ + data, + filename: `${slugify(doc.metadata.source)}-${data.id}`, + destinationOverride: outFolderPath, + }); + } + + return { + success: true, + reason: null, + data: { + author: repo.author, + repo: repo.project, + branch: repo.branch, + files: docs.length, + destination: outFolder, + }, + }; +} + +/** + * Gets the page content from a specific source file in a give GitHub Repo, not all items in a repo. + * @returns + */ +async function fetchGithubFile({ + repoUrl, + branch, + accessToken = null, + sourceFilePath, +}) { + const repo = new RepoLoader({ + repo: repoUrl, + branch, + accessToken, + }); + await repo.init(); + + if (!repo.ready) + return { + success: false, + content: null, + reason: "Could not prepare GitHub repo for loading! Check URL or PAT.", + }; + + console.log( + `-- Working GitHub ${repo.author}/${repo.project}:${repo.branch} file:${sourceFilePath} --` + ); + const fileContent = await repo.fetchSingleFile(sourceFilePath); + if (!fileContent) { + return { + success: false, + reason: "Target file returned a null content response.", + content: null, + }; + } + + return { + success: true, + reason: null, + content: fileContent, + }; +} + +/** + * Generate the full chunkSource for a specific file so that we can resync it later. + * This data is encrypted into a single `payload` query param so we can replay credentials later + * since this was encrypted with the systems persistent password and salt. + * @param {RepoLoader} repo + * @param {import("@langchain/core/documents").Document} doc + * @param {import("../../EncryptionWorker").EncryptionWorker} encryptionWorker + * @returns {string} + */ +function generateChunkSource(repo, doc, encryptionWorker) { + const payload = { + owner: repo.author, + project: repo.project, + branch: repo.branch, + path: doc.metadata.source, + pat: !!repo.accessToken ? repo.accessToken : null, + }; + return `github://${repo.repo}?payload=${encryptionWorker.encrypt( + JSON.stringify(payload) + )}`; +} + +module.exports = { loadGithubRepo, fetchGithubFile }; diff --git a/collector/utils/extensions/RepoLoader/GitlabRepo/RepoLoader/index.js b/collector/utils/extensions/RepoLoader/GitlabRepo/RepoLoader/index.js new file mode 100644 index 0000000000000000000000000000000000000000..c6c4ee244a2c0caeb3e31241b09eec542235a310 --- /dev/null +++ b/collector/utils/extensions/RepoLoader/GitlabRepo/RepoLoader/index.js @@ -0,0 +1,400 @@ +const ignore = require("ignore"); + +/** + * @typedef {Object} RepoLoaderArgs + * @property {string} repo - The GitLab repository URL. + * @property {string} [branch] - The branch to load from (optional). + * @property {string} [accessToken] - GitLab access token for authentication (optional). + * @property {string[]} [ignorePaths] - Array of paths to ignore when loading (optional). + * @property {boolean} [fetchIssues] - Should issues be fetched (optional). + * @property {boolean} [fetchWikis] - Should wiki be fetched (optional). + */ + +/** + * @typedef {Object} FileTreeObject + * @property {string} id - The file object ID. + * @property {string} name - name of file. + * @property {('blob'|'tree')} type - type of file object. + * @property {string} path - path + name of file. + * @property {string} mode - Linux permission code. + */ + +/** + * @class + * @classdesc Loads and manages GitLab repository content. + */ +class GitLabRepoLoader { + /** + * Creates an instance of RepoLoader. + * @param {RepoLoaderArgs} [args] - The configuration options. + * @returns {GitLabRepoLoader} + */ + constructor(args = {}) { + this.ready = false; + this.repo = args?.repo; + this.branch = args?.branch; + this.accessToken = args?.accessToken || null; + this.ignorePaths = args?.ignorePaths || []; + this.ignoreFilter = ignore().add(this.ignorePaths); + this.withIssues = args?.fetchIssues || false; + this.withWikis = args?.fetchWikis || false; + + this.projectId = null; + this.apiBase = "https://gitlab.com"; + this.author = null; + this.project = null; + this.branches = []; + } + + #validGitlabUrl() { + const validPatterns = [ + /https:\/\/gitlab\.com\/(?[^\/]+)\/(?.*)/, + // This should even match the regular hosted URL, but we may want to know + // if this was a hosted GitLab (above) or a self-hosted (below) instance + // since the API interface could be different. + /(http|https):\/\/[^\/]+\/(?[^\/]+)\/(?.*)/, + ]; + + const match = validPatterns + .find((pattern) => this.repo.match(pattern)?.groups) + ?.exec(this.repo); + if (!match?.groups) return false; + + const { author, project } = match.groups; + this.projectId = encodeURIComponent(`${author}/${project}`); + this.apiBase = new URL(this.repo).origin; + this.author = author; + this.project = project; + return true; + } + + async #validBranch() { + await this.getRepoBranches(); + if (!!this.branch && this.branches.includes(this.branch)) return; + + console.log( + "[Gitlab Loader]: Branch not set! Auto-assigning to a default branch." + ); + this.branch = this.branches.includes("main") ? "main" : "master"; + console.log(`[Gitlab Loader]: Branch auto-assigned to ${this.branch}.`); + return; + } + + async #validateAccessToken() { + if (!this.accessToken) return; + try { + await fetch(`${this.apiBase}/api/v4/user`, { + method: "GET", + headers: this.accessToken ? { "PRIVATE-TOKEN": this.accessToken } : {}, + }).then((res) => res.ok); + } catch (e) { + console.error( + "Invalid Gitlab Access Token provided! Access token will not be used", + e.message + ); + this.accessToken = null; + } + } + + /** + * Initializes the RepoLoader instance. + * @returns {Promise} The initialized RepoLoader instance. + */ + async init() { + if (!this.#validGitlabUrl()) return; + await this.#validBranch(); + await this.#validateAccessToken(); + this.ready = true; + return this; + } + + /** + * Recursively loads the repository content. + * @returns {Promise>} An array of loaded documents. + * @throws {Error} If the RepoLoader is not in a ready state. + */ + async recursiveLoader() { + if (!this.ready) throw new Error("[Gitlab Loader]: not in ready state!"); + + if (this.accessToken) + console.log( + `[Gitlab Loader]: Access token set! Recursive loading enabled for ${this.repo}!` + ); + + const docs = []; + + console.log(`[Gitlab Loader]: Fetching files.`); + + const files = await this.fetchFilesRecursive(); + + console.log(`[Gitlab Loader]: Fetched ${files.length} files.`); + + for (const file of files) { + if (this.ignoreFilter.ignores(file.path)) continue; + + docs.push({ + pageContent: file.content, + metadata: { + source: file.path, + url: `${this.repo}/-/blob/${this.branch}/${file.path}`, + }, + }); + } + + if (this.withIssues) { + console.log(`[Gitlab Loader]: Fetching issues.`); + const issues = await this.fetchIssues(); + console.log( + `[Gitlab Loader]: Fetched ${issues.length} issues with discussions.` + ); + docs.push( + ...issues.map((issue) => ({ + issue, + metadata: { + source: `issue-${this.repo}-${issue.iid}`, + url: issue.web_url, + }, + })) + ); + } + + if (this.withWikis) { + console.log(`[Gitlab Loader]: Fetching wiki.`); + const wiki = await this.fetchWiki(); + console.log(`[Gitlab Loader]: Fetched ${wiki.length} wiki pages.`); + docs.push( + ...wiki.map((wiki) => ({ + wiki, + metadata: { + source: `wiki-${this.repo}-${wiki.slug}`, + url: `${this.repo}/-/wikis/${wiki.slug}`, + }, + })) + ); + } + + return docs; + } + + #branchPrefSort(branches = []) { + const preferredSort = ["main", "master"]; + return branches.reduce((acc, branch) => { + if (preferredSort.includes(branch)) return [branch, ...acc]; + return [...acc, branch]; + }, []); + } + + /** + * Retrieves all branches for the repository. + * @returns {Promise} An array of branch names. + */ + async getRepoBranches() { + if (!this.#validGitlabUrl() || !this.projectId) return []; + await this.#validateAccessToken(); + this.branches = []; + + const branchesRequestData = { + endpoint: `/api/v4/projects/${this.projectId}/repository/branches`, + }; + + let branchesPage = []; + while ((branchesPage = await this.fetchNextPage(branchesRequestData))) { + this.branches.push(...branchesPage.map((branch) => branch.name)); + } + return this.#branchPrefSort(this.branches); + } + + /** + * Returns list of all file objects from tree API for GitLab + * @returns {Promise} + */ + async fetchFilesRecursive() { + const files = []; + const filesRequestData = { + endpoint: `/api/v4/projects/${this.projectId}/repository/tree`, + queryParams: { + ref: this.branch, + recursive: true, + }, + }; + + let filesPage = null; + let pagePromises = []; + while ((filesPage = await this.fetchNextPage(filesRequestData))) { + // Fetch all the files that are not ignored in parallel. + pagePromises = filesPage + .filter((file) => { + if (file.type !== "blob") return false; + return !this.ignoreFilter.ignores(file.path); + }) + .map(async (file) => { + const content = await this.fetchSingleFileContents(file.path); + if (!content) return null; + return { + path: file.path, + content, + }; + }); + + const pageFiles = await Promise.all(pagePromises); + + files.push(...pageFiles.filter((item) => item !== null)); + console.log(`Fetched ${files.length} files.`); + } + console.log(`Total files fetched: ${files.length}`); + return files; + } + + /** + * Fetches all issues from the repository. + * @returns {Promise} An array of issue objects. + */ + async fetchIssues() { + const issues = []; + const issuesRequestData = { + endpoint: `/api/v4/projects/${this.projectId}/issues`, + }; + + let issuesPage = null; + let pagePromises = []; + while ((issuesPage = await this.fetchNextPage(issuesRequestData))) { + // Fetch all the issues in parallel. + pagePromises = issuesPage.map(async (issue) => { + const discussionsRequestData = { + endpoint: `/api/v4/projects/${this.projectId}/issues/${issue.iid}/discussions`, + }; + let discussionPage = null; + const discussions = []; + + while ( + (discussionPage = await this.fetchNextPage(discussionsRequestData)) + ) { + discussions.push( + ...discussionPage.map(({ notes }) => + notes.map( + ({ body, author, created_at }) => + `${author.username} at ${created_at}: +${body}` + ) + ) + ); + } + const result = { + ...issue, + discussions, + }; + return result; + }); + + const pageIssues = await Promise.all(pagePromises); + + issues.push(...pageIssues); + console.log(`Fetched ${issues.length} issues.`); + } + console.log(`Total issues fetched: ${issues.length}`); + return issues; + } + + /** + * Fetches all wiki pages from the repository. + * @returns {Promise} An array of wiki page objects. + */ + async fetchWiki() { + const wikiRequestData = { + endpoint: `/api/v4/projects/${this.projectId}/wikis`, + queryParams: { + with_content: "1", + }, + }; + + const wikiPages = await this.fetchNextPage(wikiRequestData); + console.log(`Total wiki pages fetched: ${wikiPages.length}`); + return wikiPages; + } + + /** + * Fetches the content of a single file from the repository. + * @param {string} sourceFilePath - The path to the file in the repository. + * @returns {Promise} The content of the file, or null if fetching fails. + */ + async fetchSingleFileContents(sourceFilePath) { + try { + const data = await fetch( + `${this.apiBase}/api/v4/projects/${ + this.projectId + }/repository/files/${encodeURIComponent(sourceFilePath)}/raw?ref=${ + this.branch + }`, + { + method: "GET", + headers: this.accessToken + ? { "PRIVATE-TOKEN": this.accessToken } + : {}, + } + ).then((res) => { + if (res.ok) return res.text(); + throw new Error(`Failed to fetch single file ${sourceFilePath}`); + }); + + return data; + } catch (e) { + console.error(`RepoLoader.fetchSingleFileContents`, e); + return null; + } + } + + /** + * Fetches the next page of data from the API. + * @param {Object} requestData - The request data. + * @returns {Promise|null>} The next page of data, or null if no more pages. + */ + async fetchNextPage(requestData) { + try { + if (requestData.page === -1) return null; + if (!requestData.page) requestData.page = 1; + + const { endpoint, perPage = 100, queryParams = {} } = requestData; + const params = new URLSearchParams({ + ...queryParams, + per_page: perPage, + page: requestData.page, + }); + const url = `${this.apiBase}${endpoint}?${params.toString()}`; + + const response = await fetch(url, { + method: "GET", + headers: this.accessToken ? { "PRIVATE-TOKEN": this.accessToken } : {}, + }); + + // Rate limits get hit very often if no PAT is provided + if (response.status === 401) { + console.warn(`Rate limit hit for ${endpoint}. Skipping.`); + return null; + } + + const totalPages = Number(response.headers.get("x-total-pages")); + const data = await response.json(); + if (!Array.isArray(data)) { + console.warn(`Unexpected response format for ${endpoint}:`, data); + return []; + } + + console.log( + `Gitlab RepoLoader: fetched ${endpoint} page ${requestData.page}/${totalPages} with ${data.length} records.` + ); + + if (totalPages === requestData.page) { + requestData.page = -1; + } else { + requestData.page = Number(response.headers.get("x-next-page")); + } + + return data; + } catch (e) { + console.error(`RepoLoader.fetchNextPage`, e); + return null; + } + } +} + +module.exports = GitLabRepoLoader; diff --git a/collector/utils/extensions/RepoLoader/GitlabRepo/index.js b/collector/utils/extensions/RepoLoader/GitlabRepo/index.js new file mode 100644 index 0000000000000000000000000000000000000000..5c312f0225914e11c7b9fb23af93e4c694748c61 --- /dev/null +++ b/collector/utils/extensions/RepoLoader/GitlabRepo/index.js @@ -0,0 +1,261 @@ +const RepoLoader = require("./RepoLoader"); +const fs = require("fs"); +const path = require("path"); +const { default: slugify } = require("slugify"); +const { v4 } = require("uuid"); +const { sanitizeFileName, writeToServerDocuments } = require("../../../files"); +const { tokenizeString } = require("../../../tokenizer"); + +/** + * Load in a Gitlab Repo recursively or just the top level if no PAT is provided + * @param {object} args - forwarded request body params + * @param {import("../../../middleware/setDataSigner").ResponseWithSigner} response - Express response object with encryptionWorker + * @returns + */ +async function loadGitlabRepo(args, response) { + const repo = new RepoLoader(args); + await repo.init(); + + if (!repo.ready) + return { + success: false, + reason: "Could not prepare Gitlab repo for loading! Check URL", + }; + + console.log( + `-- Working GitLab ${repo.author}/${repo.project}:${repo.branch} --` + ); + const docs = await repo.recursiveLoader(); + if (!docs.length) { + return { + success: false, + reason: "No files were found for those settings.", + }; + } + + console.log(`[GitLab Loader]: Found ${docs.length} source files. Saving...`); + const outFolder = slugify( + `${repo.author}-${repo.project}-${repo.branch}-${v4().slice(0, 4)}` + ).toLowerCase(); + + const outFolderPath = + process.env.NODE_ENV === "development" + ? path.resolve( + __dirname, + `../../../../../server/storage/documents/${outFolder}` + ) + : path.resolve(process.env.STORAGE_DIR, `documents/${outFolder}`); + + if (!fs.existsSync(outFolderPath)) + fs.mkdirSync(outFolderPath, { recursive: true }); + + for (const doc of docs) { + if (!doc.metadata || (!doc.pageContent && !doc.issue && !doc.wiki)) + continue; + let pageContent = null; + + const data = { + id: v4(), + url: "gitlab://" + doc.metadata.source, + docSource: doc.metadata.source, + chunkSource: generateChunkSource( + repo, + doc, + response.locals.encryptionWorker + ), + published: new Date().toLocaleString(), + }; + + if (doc.pageContent) { + pageContent = doc.pageContent; + + data.title = doc.metadata.source; + data.docAuthor = repo.author; + data.description = "No description found."; + } else if (doc.issue) { + pageContent = issueToMarkdown(doc.issue); + + data.title = `Issue ${doc.issue.iid}: ${doc.issue.title}`; + data.docAuthor = doc.issue.author.username; + data.description = doc.issue.description; + } else if (doc.wiki) { + pageContent = doc.wiki.content; + data.title = doc.wiki.title; + data.docAuthor = repo.author; + data.description = + doc.wiki.format === "markdown" + ? "GitLab Wiki Page (Markdown)" + : "GitLab Wiki Page"; + } else { + continue; + } + + data.wordCount = pageContent.split(" ").length; + data.token_count_estimate = tokenizeString(pageContent); + data.pageContent = pageContent; + + console.log( + `[GitLab Loader]: Saving ${doc.metadata.source} to ${outFolder}` + ); + + writeToServerDocuments({ + data, + filename: sanitizeFileName(`${slugify(doc.metadata.source)}-${data.id}`), + destinationOverride: outFolderPath, + }); + } + + return { + success: true, + reason: null, + data: { + author: repo.author, + repo: repo.project, + projectId: repo.projectId, + branch: repo.branch, + files: docs.length, + destination: outFolder, + }, + }; +} + +async function fetchGitlabFile({ + repoUrl, + branch, + accessToken = null, + sourceFilePath, +}) { + const repo = new RepoLoader({ + repo: repoUrl, + branch, + accessToken, + }); + await repo.init(); + + if (!repo.ready) + return { + success: false, + content: null, + reason: "Could not prepare GitLab repo for loading! Check URL or PAT.", + }; + console.log( + `-- Working GitLab ${repo.author}/${repo.project}:${repo.branch} file:${sourceFilePath} --` + ); + const fileContent = await repo.fetchSingleFile(sourceFilePath); + if (!fileContent) { + return { + success: false, + reason: "Target file returned a null content response.", + content: null, + }; + } + + return { + success: true, + reason: null, + content: fileContent, + }; +} + +function generateChunkSource(repo, doc, encryptionWorker) { + const payload = { + projectId: decodeURIComponent(repo.projectId), + branch: repo.branch, + path: doc.metadata.source, + pat: !!repo.accessToken ? repo.accessToken : null, + }; + return `gitlab://${repo.repo}?payload=${encryptionWorker.encrypt( + JSON.stringify(payload) + )}`; +} + +function issueToMarkdown(issue) { + const metadata = {}; + + const userFields = ["author", "assignees", "closed_by"]; + const userToUsername = ({ username }) => username; + for (const userField of userFields) { + if (issue[userField]) { + if (Array.isArray(issue[userField])) { + metadata[userField] = issue[userField].map(userToUsername); + } else { + metadata[userField] = userToUsername(issue[userField]); + } + } + } + + const singleValueFields = [ + "web_url", + "state", + "created_at", + "updated_at", + "closed_at", + "due_date", + "type", + "merge_request_count", + "upvotes", + "downvotes", + "labels", + "has_tasks", + "task_status", + "confidential", + "severity", + ]; + + for (const singleValueField of singleValueFields) { + metadata[singleValueField] = issue[singleValueField]; + } + + if (issue.milestone) { + metadata.milestone = `${issue.milestone.title} (${issue.milestone.id})`; + } + + if (issue.time_stats) { + const timeFields = ["time_estimate", "total_time_spent"]; + for (const timeField of timeFields) { + const fieldName = `human_${timeField}`; + if (issue?.time_stats[fieldName]) { + metadata[timeField] = issue.time_stats[fieldName]; + } + } + } + + const metadataString = Object.entries(metadata) + .map(([name, value]) => { + if (!value || value?.length < 1) { + return null; + } + let result = `- ${name.replace("_", " ")}:`; + + if (!Array.isArray(value)) { + result += ` ${value}`; + } else { + result += "\n" + value.map((s) => ` - ${s}`).join("\n"); + } + + return result; + }) + .filter((item) => item != null) + .join("\n"); + + let markdown = `# ${issue.title} (${issue.iid}) + +${issue.description} + +## Metadata + +${metadataString}`; + + if (issue.discussions.length > 0) { + markdown += ` + +## Activity + +${issue.discussions.join("\n\n")} +`; + } + + return markdown; +} + +module.exports = { loadGitlabRepo, fetchGitlabFile }; diff --git a/collector/utils/extensions/RepoLoader/index.js b/collector/utils/extensions/RepoLoader/index.js new file mode 100644 index 0000000000000000000000000000000000000000..28e8780239e0b9cc7dfb02d6e3c861e9d830c617 --- /dev/null +++ b/collector/utils/extensions/RepoLoader/index.js @@ -0,0 +1,41 @@ +/** + * Dynamically load the correct repository loader from a specific platform + * by default will return GitHub. + * @param {('github'|'gitlab')} platform + * @returns {import("./GithubRepo/RepoLoader")|import("./GitlabRepo/RepoLoader")} the repo loader class for provider + */ +function resolveRepoLoader(platform = "github") { + switch (platform) { + case "github": + console.log(`Loading GitHub RepoLoader...`); + return require("./GithubRepo/RepoLoader"); + case "gitlab": + console.log(`Loading GitLab RepoLoader...`); + return require("./GitlabRepo/RepoLoader"); + default: + console.log(`Loading GitHub RepoLoader...`); + return require("./GithubRepo/RepoLoader"); + } +} + +/** + * Dynamically load the correct repository loader function from a specific platform + * by default will return Github. + * @param {('github'|'gitlab')} platform + * @returns {import("./GithubRepo")['fetchGithubFile'] | import("./GitlabRepo")['fetchGitlabFile']} the repo loader class for provider + */ +function resolveRepoLoaderFunction(platform = "github") { + switch (platform) { + case "github": + console.log(`Loading GitHub loader function...`); + return require("./GithubRepo").loadGithubRepo; + case "gitlab": + console.log(`Loading GitLab loader function...`); + return require("./GitlabRepo").loadGitlabRepo; + default: + console.log(`Loading GitHub loader function...`); + return require("./GithubRepo").loadGithubRepo; + } +} + +module.exports = { resolveRepoLoader, resolveRepoLoaderFunction }; diff --git a/collector/utils/extensions/WebsiteDepth/index.js b/collector/utils/extensions/WebsiteDepth/index.js new file mode 100644 index 0000000000000000000000000000000000000000..dca2255856107dac52e41916422177f94d01bb5c --- /dev/null +++ b/collector/utils/extensions/WebsiteDepth/index.js @@ -0,0 +1,170 @@ +const { v4 } = require("uuid"); +const { + PuppeteerWebBaseLoader, +} = require("langchain/document_loaders/web/puppeteer"); +const { default: slugify } = require("slugify"); +const { parse } = require("node-html-parser"); +const { writeToServerDocuments } = require("../../files"); +const { tokenizeString } = require("../../tokenizer"); +const path = require("path"); +const fs = require("fs"); + +async function discoverLinks(startUrl, maxDepth = 1, maxLinks = 20) { + const baseUrl = new URL(startUrl); + const discoveredLinks = new Set([startUrl]); + let queue = [[startUrl, 0]]; // [url, currentDepth] + const scrapedUrls = new Set(); + + for (let currentDepth = 0; currentDepth < maxDepth; currentDepth++) { + const levelSize = queue.length; + const nextQueue = []; + + for (let i = 0; i < levelSize && discoveredLinks.size < maxLinks; i++) { + const [currentUrl, urlDepth] = queue[i]; + + if (!scrapedUrls.has(currentUrl)) { + scrapedUrls.add(currentUrl); + const newLinks = await getPageLinks(currentUrl, baseUrl); + + for (const link of newLinks) { + if (!discoveredLinks.has(link) && discoveredLinks.size < maxLinks) { + discoveredLinks.add(link); + if (urlDepth + 1 < maxDepth) { + nextQueue.push([link, urlDepth + 1]); + } + } + } + } + } + + queue = nextQueue; + if (queue.length === 0 || discoveredLinks.size >= maxLinks) break; + } + + return Array.from(discoveredLinks); +} + +async function getPageLinks(url, baseUrl) { + try { + const loader = new PuppeteerWebBaseLoader(url, { + launchOptions: { headless: "new" }, + gotoOptions: { waitUntil: "networkidle2" }, + }); + const docs = await loader.load(); + const html = docs[0].pageContent; + const links = extractLinks(html, baseUrl); + return links; + } catch (error) { + console.error(`Failed to get page links from ${url}.`, error); + return []; + } +} + +function extractLinks(html, baseUrl) { + const root = parse(html); + const links = root.querySelectorAll("a"); + const extractedLinks = new Set(); + + for (const link of links) { + const href = link.getAttribute("href"); + if (href) { + const absoluteUrl = new URL(href, baseUrl.href).href; + if ( + absoluteUrl.startsWith( + baseUrl.origin + baseUrl.pathname.split("/").slice(0, -1).join("/") + ) + ) { + extractedLinks.add(absoluteUrl); + } + } + } + + return Array.from(extractedLinks); +} + +async function bulkScrapePages(links, outFolderPath) { + const scrapedData = []; + + for (let i = 0; i < links.length; i++) { + const link = links[i]; + console.log(`Scraping ${i + 1}/${links.length}: ${link}`); + + try { + const loader = new PuppeteerWebBaseLoader(link, { + launchOptions: { headless: "new" }, + gotoOptions: { waitUntil: "networkidle2" }, + async evaluate(page, browser) { + const result = await page.evaluate(() => document.body.innerText); + await browser.close(); + return result; + }, + }); + const docs = await loader.load(); + const content = docs[0].pageContent; + + if (!content.length) { + console.warn(`Empty content for ${link}. Skipping.`); + continue; + } + + const url = new URL(link); + const decodedPathname = decodeURIComponent(url.pathname); + const filename = `${url.hostname}${decodedPathname.replace(/\//g, "_")}`; + + const data = { + id: v4(), + url: "file://" + slugify(filename) + ".html", + title: slugify(filename) + ".html", + docAuthor: "no author found", + description: "No description found.", + docSource: "URL link uploaded by the user.", + chunkSource: `link://${link}`, + published: new Date().toLocaleString(), + wordCount: content.split(" ").length, + pageContent: content, + token_count_estimate: tokenizeString(content), + }; + + writeToServerDocuments({ + data, + filename: data.title, + destinationOverride: outFolderPath, + }); + scrapedData.push(data); + + console.log(`Successfully scraped ${link}.`); + } catch (error) { + console.error(`Failed to scrape ${link}.`, error); + } + } + + return scrapedData; +} + +async function websiteScraper(startUrl, depth = 1, maxLinks = 20) { + const websiteName = new URL(startUrl).hostname; + const outFolder = slugify( + `${slugify(websiteName)}-${v4().slice(0, 4)}` + ).toLowerCase(); + const outFolderPath = + process.env.NODE_ENV === "development" + ? path.resolve( + __dirname, + `../../../../server/storage/documents/${outFolder}` + ) + : path.resolve(process.env.STORAGE_DIR, `documents/${outFolder}`); + + console.log("Discovering links..."); + const linksToScrape = await discoverLinks(startUrl, depth, maxLinks); + console.log(`Found ${linksToScrape.length} links to scrape.`); + + if (!fs.existsSync(outFolderPath)) + fs.mkdirSync(outFolderPath, { recursive: true }); + console.log("Starting bulk scraping..."); + const scrapedData = await bulkScrapePages(linksToScrape, outFolderPath); + console.log(`Scraped ${scrapedData.length} pages.`); + + return scrapedData; +} + +module.exports = websiteScraper; diff --git a/collector/utils/extensions/YoutubeTranscript/YoutubeLoader/index.js b/collector/utils/extensions/YoutubeTranscript/YoutubeLoader/index.js new file mode 100644 index 0000000000000000000000000000000000000000..aac94eb482f4708776ae9559bf78b7ed70778aad --- /dev/null +++ b/collector/utils/extensions/YoutubeTranscript/YoutubeLoader/index.js @@ -0,0 +1,90 @@ +/* + * This is just a custom implementation of the Langchain JS YouTubeLoader class + * as the dependency for YoutubeTranscript is quite fickle and its a rat race to keep it up + * and instead of waiting for patches we can just bring this simple script in-house and at least + * be able to patch it since its so flaky. When we have more connectors we can kill this because + * it will be a pain to maintain over time. + */ +class YoutubeLoader { + #videoId; + #language; + #addVideoInfo; + + constructor({ videoId = null, language = null, addVideoInfo = false } = {}) { + if (!videoId) throw new Error("Invalid video id!"); + this.#videoId = videoId; + this.#language = language; + this.#addVideoInfo = addVideoInfo; + } + + /** + * Extracts the videoId from a YouTube video URL. + * @param url The URL of the YouTube video. + * @returns The videoId of the YouTube video. + */ + static getVideoID(url) { + const match = url.match( + /.*(?:youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=)([^#&?]*).*/ + ); + if (match !== null && match[1].length === 11) { + return match[1]; + } else { + throw new Error("Failed to get youtube video id from the url"); + } + } + + /** + * Creates a new instance of the YoutubeLoader class from a YouTube video + * URL. + * @param url The URL of the YouTube video. + * @param config Optional configuration options for the YoutubeLoader instance, excluding the videoId. + * @returns A new instance of the YoutubeLoader class. + */ + static createFromUrl(url, config = {}) { + const videoId = YoutubeLoader.getVideoID(url); + return new YoutubeLoader({ ...config, videoId }); + } + + /** + * Loads the transcript and video metadata from the specified YouTube + * video. It uses the youtube-transcript library to fetch the transcript + * and the youtubei.js library to fetch the video metadata. + * @returns Langchain like doc that is 1 element with PageContent and + */ + async load() { + let transcript; + const metadata = { + source: this.#videoId, + }; + try { + const { YoutubeTranscript } = require("./youtube-transcript"); + transcript = await YoutubeTranscript.fetchTranscript(this.#videoId, { + lang: this.#language, + }); + if (!transcript) { + throw new Error("Transcription not found"); + } + if (this.#addVideoInfo) { + const { Innertube } = require("youtubei.js"); + const youtube = await Innertube.create(); + const info = (await youtube.getBasicInfo(this.#videoId)).basic_info; + metadata.description = info.short_description; + metadata.title = info.title; + metadata.view_count = info.view_count; + metadata.author = info.author; + } + } catch (e) { + throw new Error( + `Failed to get YouTube video transcription: ${e?.message}` + ); + } + return [ + { + pageContent: transcript, + metadata, + }, + ]; + } +} + +module.exports.YoutubeLoader = YoutubeLoader; diff --git a/collector/utils/extensions/YoutubeTranscript/YoutubeLoader/youtube-transcript.js b/collector/utils/extensions/YoutubeTranscript/YoutubeLoader/youtube-transcript.js new file mode 100644 index 0000000000000000000000000000000000000000..3f0a4c4371f545c611d914af4a8d922a59146218 --- /dev/null +++ b/collector/utils/extensions/YoutubeTranscript/YoutubeLoader/youtube-transcript.js @@ -0,0 +1,163 @@ +class YoutubeTranscriptError extends Error { + constructor(message) { + super(`[YoutubeTranscript] ${message}`); + } +} + +/** + * Handles fetching and parsing YouTube video transcripts + */ +class YoutubeTranscript { + /** + * Encodes a string as a protobuf field + * @param {number} fieldNumber - The protobuf field number + * @param {string} str - The string to encode + * @returns {Buffer} Encoded protobuf field + */ + static #encodeProtobufString(fieldNumber, str) { + const utf8Bytes = Buffer.from(str, "utf8"); + const tag = (fieldNumber << 3) | 2; // wire type 2 for string + const lengthBytes = this.#encodeVarint(utf8Bytes.length); + + return Buffer.concat([ + Buffer.from([tag]), + Buffer.from(lengthBytes), + utf8Bytes, + ]); + } + + /** + * Encodes a number as a protobuf varint + * @param {number} value - The number to encode + * @returns {number[]} Encoded varint bytes + */ + static #encodeVarint(value) { + const bytes = []; + while (value >= 0x80) { + bytes.push((value & 0x7f) | 0x80); + value >>>= 7; + } + bytes.push(value); + return bytes; + } + + /** + * Creates a base64 encoded protobuf message + * @param {Object} param - The parameters to encode + * @param {string} param.param1 - First parameter + * @param {string} param.param2 - Second parameter + * @returns {string} Base64 encoded protobuf + */ + static #getBase64Protobuf({ param1, param2 }) { + const field1 = this.#encodeProtobufString(1, param1); + const field2 = this.#encodeProtobufString(2, param2); + return Buffer.concat([field1, field2]).toString("base64"); + } + + /** + * Extracts transcript text from YouTube API response + * @param {Object} responseData - The YouTube API response + * @returns {string} Combined transcript text + */ + static #extractTranscriptFromResponse(responseData) { + const transcriptRenderer = + responseData.actions?.[0]?.updateEngagementPanelAction?.content + ?.transcriptRenderer; + if (!transcriptRenderer) { + throw new Error("No transcript data found in response"); + } + + const segments = + transcriptRenderer.content?.transcriptSearchPanelRenderer?.body + ?.transcriptSegmentListRenderer?.initialSegments; + if (!segments) { + throw new Error("Transcript segments not found in response"); + } + + return segments + .map((segment) => { + const runs = segment.transcriptSegmentRenderer?.snippet?.runs; + return runs ? runs.map((run) => run.text).join("") : ""; + }) + .filter((text) => text) + .join(" ") + .trim() + .replace(/\s+/g, " "); + } + + /** + * Fetch transcript from YouTube video + * @param {string} videoId - Video URL or video identifier + * @param {Object} config - Configuration options + * @param {string} [config.lang='en'] - Language code (e.g., 'en', 'es', 'fr') + * @returns {Promise} Video transcript text + */ + static async fetchTranscript(videoId, config = {}) { + const identifier = this.retrieveVideoId(videoId); + const lang = config?.lang ?? "en"; + + try { + const innerProto = this.#getBase64Protobuf({ + param1: "asr", + param2: lang, + }); + const params = this.#getBase64Protobuf({ + param1: identifier, + param2: innerProto, + }); + + const response = await fetch( + "https://www.youtube.com/youtubei/v1/get_transcript", + { + method: "POST", + headers: { + "Content-Type": "application/json", + "User-Agent": + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36,gzip(gfe)", + }, + body: JSON.stringify({ + context: { + client: { + clientName: "WEB", + clientVersion: "2.20240826.01.00", + }, + }, + params, + }), + } + ); + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + + const responseData = await response.json(); + return this.#extractTranscriptFromResponse(responseData); + } catch (e) { + throw new YoutubeTranscriptError(e.message || e); + } + } + + /** + * Extract video ID from a YouTube URL or verify an existing ID + * @param {string} videoId - Video URL or ID + * @returns {string} YouTube video ID + */ + static retrieveVideoId(videoId) { + if (videoId.length === 11) return videoId; + + const RE_YOUTUBE = + /(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=)|youtu\.be\/)([^"&?\/\s]{11})/i; + const matchId = videoId.match(RE_YOUTUBE); + + if (matchId?.[1]) return matchId[1]; + throw new YoutubeTranscriptError( + "Impossible to retrieve Youtube video ID." + ); + } +} + +module.exports = { + YoutubeTranscript, + YoutubeTranscriptError, +}; diff --git a/collector/utils/extensions/YoutubeTranscript/index.js b/collector/utils/extensions/YoutubeTranscript/index.js new file mode 100644 index 0000000000000000000000000000000000000000..b0b4f1313f180de8e05549cae0281c43a8a3d01b --- /dev/null +++ b/collector/utils/extensions/YoutubeTranscript/index.js @@ -0,0 +1,139 @@ +const fs = require("fs"); +const path = require("path"); +const { default: slugify } = require("slugify"); +const { v4 } = require("uuid"); +const { + writeToServerDocuments, + sanitizeFileName, + documentsFolder, +} = require("../../files"); +const { tokenizeString } = require("../../tokenizer"); +const { YoutubeLoader } = require("./YoutubeLoader"); + +function validYoutubeVideoUrl(link) { + const UrlPattern = require("url-pattern"); + const opts = new URL(link); + const url = `${opts.protocol}//${opts.host}${opts.pathname}${ + opts.searchParams.has("v") ? `?v=${opts.searchParams.get("v")}` : "" + }`; + + const shortPatternMatch = new UrlPattern( + "https\\://(www.)youtu.be/(:videoId)" + ).match(url); + const fullPatternMatch = new UrlPattern( + "https\\://(www.)youtube.com/watch?v=(:videoId)" + ).match(url); + const videoId = + shortPatternMatch?.videoId || fullPatternMatch?.videoId || null; + if (!!videoId) return true; + + return false; +} + +async function fetchVideoTranscriptContent({ url }) { + if (!validYoutubeVideoUrl(url)) { + return { + success: false, + reason: "Invalid URL. Should be youtu.be or youtube.com/watch.", + content: null, + metadata: {}, + }; + } + + console.log(`-- Working YouTube ${url} --`); + const loader = YoutubeLoader.createFromUrl(url, { addVideoInfo: true }); + const { docs, error } = await loader + .load() + .then((docs) => { + return { docs, error: null }; + }) + .catch((e) => { + return { + docs: [], + error: e.message?.split("Error:")?.[1] || e.message, + }; + }); + + if (!docs.length || !!error) { + return { + success: false, + reason: error ?? "No transcript found for that YouTube video.", + content: null, + metadata: {}, + }; + } + + const metadata = docs[0].metadata; + const content = docs[0].pageContent; + if (!content.length) { + return { + success: false, + reason: "No transcript could be parsed for that YouTube video.", + content: null, + metadata: {}, + }; + } + + return { + success: true, + reason: null, + content, + metadata, + }; +} + +async function loadYouTubeTranscript({ url }) { + const transcriptResults = await fetchVideoTranscriptContent({ url }); + if (!transcriptResults.success) { + return { + success: false, + reason: + transcriptResults.reason || + "An unknown error occurred during transcription retrieval", + }; + } + const { content, metadata } = transcriptResults; + const outFolder = sanitizeFileName( + slugify(`${metadata.author} YouTube transcripts`).toLowerCase() + ); + const outFolderPath = path.resolve(documentsFolder, outFolder); + + if (!fs.existsSync(outFolderPath)) + fs.mkdirSync(outFolderPath, { recursive: true }); + + const data = { + id: v4(), + url: url + ".youtube", + title: metadata.title || url, + docAuthor: metadata.author, + description: metadata.description, + docSource: url, + chunkSource: `youtube://${url}`, + published: new Date().toLocaleString(), + wordCount: content.split(" ").length, + pageContent: content, + token_count_estimate: tokenizeString(content), + }; + + console.log(`[YouTube Loader]: Saving ${metadata.title} to ${outFolder}`); + writeToServerDocuments({ + data, + filename: sanitizeFileName(`${slugify(metadata.title)}-${data.id}`), + destinationOverride: outFolderPath, + }); + + return { + success: true, + reason: "test", + data: { + title: metadata.title, + author: metadata.author, + destination: outFolder, + }, + }; +} + +module.exports = { + loadYouTubeTranscript, + fetchVideoTranscriptContent, +}; diff --git a/collector/utils/files/index.js b/collector/utils/files/index.js new file mode 100644 index 0000000000000000000000000000000000000000..6e43802aef9d4864467a5fce13bdc91529079f5d --- /dev/null +++ b/collector/utils/files/index.js @@ -0,0 +1,228 @@ +const fs = require("fs"); +const path = require("path"); +const { MimeDetector } = require("./mime"); + +/** + * The folder where documents are stored to be stored when + * processed by the collector. + */ +const documentsFolder = + process.env.NODE_ENV === "development" + ? path.resolve(__dirname, `../../../server/storage/documents`) + : path.resolve(process.env.STORAGE_DIR, `documents`); + +/** + * The folder where direct uploads are stored to be stored when + * processed by the collector. These are files that were DnD'd into UI + * and are not to be embedded or selectable from the file picker. + */ +const directUploadsFolder = + process.env.NODE_ENV === "development" + ? path.resolve(__dirname, `../../../server/storage/direct-uploads`) + : path.resolve(process.env.STORAGE_DIR, `direct-uploads`); + +/** + * Checks if a file is text by checking the mime type and then falling back to buffer inspection. + * This way we can capture all the cases where the mime type is not known but still parseable as text + * without having to constantly add new mime type overrides. + * @param {string} filepath - The path to the file. + * @returns {boolean} - Returns true if the file is text, false otherwise. + */ +function isTextType(filepath) { + if (!fs.existsSync(filepath)) return false; + const result = isKnownTextMime(filepath); + if (result.valid) return true; // Known text type - return true. + if (result.reason !== "generic") return false; // If any other reason than generic - return false. + return parseableAsText(filepath); // Fallback to parsing as text via buffer inspection. +} + +/** + * Checks if a file is known to be text by checking the mime type. + * @param {string} filepath - The path to the file. + * @returns {boolean} - Returns true if the file is known to be text, false otherwise. + */ +function isKnownTextMime(filepath) { + try { + const mimeLib = new MimeDetector(); + const mime = mimeLib.getType(filepath); + if (mimeLib.badMimes.includes(mime)) + return { valid: false, reason: "bad_mime" }; + + const type = mime.split("/")[0]; + if (mimeLib.nonTextTypes.includes(type)) + return { valid: false, reason: "non_text_mime" }; + return { valid: true, reason: "valid_mime" }; + } catch (e) { + return { valid: false, reason: "generic" }; + } +} + +/** + * Checks if a file is parseable as text by forcing it to be read as text in utf8 encoding. + * If the file looks too much like a binary file, it will return false. + * @param {string} filepath - The path to the file. + * @returns {boolean} - Returns true if the file is parseable as text, false otherwise. + */ +function parseableAsText(filepath) { + try { + const fd = fs.openSync(filepath, "r"); + const buffer = Buffer.alloc(1024); // Read first 1KB of the file synchronously + const bytesRead = fs.readSync(fd, buffer, 0, 1024, 0); + fs.closeSync(fd); + + const content = buffer.subarray(0, bytesRead).toString("utf8"); + const nullCount = (content.match(/\0/g) || []).length; + const controlCount = (content.match(/[\x00-\x08\x0B\x0C\x0E-\x1F]/g) || []) + .length; + + const threshold = bytesRead * 0.1; + return nullCount + controlCount < threshold; + } catch { + return false; + } +} + +function trashFile(filepath) { + if (!fs.existsSync(filepath)) return; + + try { + const isDir = fs.lstatSync(filepath).isDirectory(); + if (isDir) return; + } catch { + return; + } + + fs.rmSync(filepath); + return; +} + +function createdDate(filepath) { + try { + const { birthtimeMs, birthtime } = fs.statSync(filepath); + if (birthtimeMs === 0) throw new Error("Invalid stat for file!"); + return birthtime.toLocaleString(); + } catch { + return "unknown"; + } +} + +/** + * Writes a document to the server documents folder. + * @param {Object} params - The parameters for the function. + * @param {Object} params.data - The data to write to the file. Must look like a document object. + * @param {string} params.filename - The name of the file to write to. + * @param {string|null} params.destinationOverride - A forced destination to write to - will be honored if provided. + * @param {Object} params.options - The options for the function. + * @param {boolean} params.options.parseOnly - If true, the file will be written to the direct uploads folder instead of the documents folder. Will be ignored if destinationOverride is provided. + * @returns {Object} - The data with the location added. + */ +function writeToServerDocuments({ + data = {}, + filename, + destinationOverride = null, + options = {}, +}) { + if (!filename) throw new Error("Filename is required!"); + + let destination = null; + if (destinationOverride) destination = path.resolve(destinationOverride); + else if (options.parseOnly) destination = path.resolve(directUploadsFolder); + else destination = path.resolve(documentsFolder, "custom-documents"); + + if (!fs.existsSync(destination)) + fs.mkdirSync(destination, { recursive: true }); + const destinationFilePath = normalizePath( + path.resolve(destination, filename) + ".json" + ); + + fs.writeFileSync(destinationFilePath, JSON.stringify(data, null, 4), { + encoding: "utf-8", + }); + + return { + ...data, + // relative location string that can be passed into the /update-embeddings api + // that will work since we know the location exists and since we only allow + // 1-level deep folders this will always work. This still works for integrations like GitHub and YouTube. + location: destinationFilePath.split("/").slice(-2).join("/"), + isDirectUpload: options.parseOnly || false, + }; +} + +// When required we can wipe the entire collector hotdir and tmp storage in case +// there were some large file failures that we unable to be removed a reboot will +// force remove them. +async function wipeCollectorStorage() { + const cleanHotDir = new Promise((resolve) => { + const directory = path.resolve(__dirname, "../../hotdir"); + fs.readdir(directory, (err, files) => { + if (err) resolve(); + + for (const file of files) { + if (file === "__HOTDIR__.md") continue; + try { + fs.rmSync(path.join(directory, file)); + } catch {} + } + resolve(); + }); + }); + + const cleanTmpDir = new Promise((resolve) => { + const directory = path.resolve(__dirname, "../../storage/tmp"); + fs.readdir(directory, (err, files) => { + if (err) resolve(); + + for (const file of files) { + if (file === ".placeholder") continue; + try { + fs.rmSync(path.join(directory, file)); + } catch {} + } + resolve(); + }); + }); + + await Promise.all([cleanHotDir, cleanTmpDir]); + console.log(`Collector hot directory and tmp storage wiped!`); + return; +} + +/** + * Checks if a given path is within another path. + * @param {string} outer - The outer path (should be resolved). + * @param {string} inner - The inner path (should be resolved). + * @returns {boolean} - Returns true if the inner path is within the outer path, false otherwise. + */ +function isWithin(outer, inner) { + if (outer === inner) return false; + const rel = path.relative(outer, inner); + return !rel.startsWith("../") && rel !== ".."; +} + +function normalizePath(filepath = "") { + const result = path + .normalize(filepath.trim()) + .replace(/^(\.\.(\/|\\|$))+/, "") + .trim(); + if (["..", ".", "/"].includes(result)) throw new Error("Invalid path."); + return result; +} + +function sanitizeFileName(fileName) { + if (!fileName) return fileName; + return fileName.replace(/[<>:"\/\\|?*]/g, ""); +} + +module.exports = { + trashFile, + isTextType, + createdDate, + writeToServerDocuments, + wipeCollectorStorage, + normalizePath, + isWithin, + sanitizeFileName, + documentsFolder, + directUploadsFolder, +}; diff --git a/collector/utils/files/mime.js b/collector/utils/files/mime.js new file mode 100644 index 0000000000000000000000000000000000000000..bd954965363b9e9835816744ab2e53cc44443f07 --- /dev/null +++ b/collector/utils/files/mime.js @@ -0,0 +1,64 @@ +const MimeLib = require("mime"); +class MimeDetector { + nonTextTypes = ["multipart", "model", "audio", "video", "font"]; + badMimes = [ + "application/octet-stream", + "application/zip", + "application/pkcs8", + "application/vnd.microsoft.portable-executable", + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", // XLSX are binaries and need to be handled explicitly. + "application/x-msdownload", + ]; + + constructor() { + this.lib = MimeLib; + this.setOverrides(); + } + + setOverrides() { + // the .ts extension maps to video/mp2t because of https://en.wikipedia.org/wiki/MPEG_transport_stream + // which has had this extension far before TS was invented. So need to force re-map this MIME map. + this.lib.define( + { + "text/plain": [ + "ts", + "tsx", + "py", + "opts", + "lock", + "jsonl", + "qml", + "sh", + "c", + "cs", + "h", + "js", + "lua", + "pas", + "r", + "go", + "ino", + "hpp", + "linq", + "cs", + ], + }, + true + ); + } + + /** + * Returns the MIME type of the file. If the file has no extension found, it will be processed as a text file. + * @param {string} filepath + * @returns {string} + */ + getType(filepath) { + const parsedMime = this.lib.getType(filepath); + if (!!parsedMime) return parsedMime; + return null; + } +} + +module.exports = { + MimeDetector, +}; diff --git a/collector/utils/http/index.js b/collector/utils/http/index.js new file mode 100644 index 0000000000000000000000000000000000000000..3648ec58e18b1ccf2e50f09f3de030eaebb26eae --- /dev/null +++ b/collector/utils/http/index.js @@ -0,0 +1,35 @@ +process.env.NODE_ENV === "development" + ? require("dotenv").config({ path: `.env.${process.env.NODE_ENV}` }) + : require("dotenv").config(); + +function reqBody(request) { + return typeof request.body === "string" + ? JSON.parse(request.body) + : request.body; +} + +function queryParams(request) { + return request.query; +} + +/** + * Validates if the provided baseUrl is a valid URL at all. + * - Does not validate if the URL is reachable or accessible. + * - Does not do any further validation of the URL like `validURL` in `utils/url/index.js` + * @param {string} baseUrl + * @returns {boolean} + */ +function validBaseUrl(baseUrl) { + try { + new URL(baseUrl); + return true; + } catch (e) { + return false; + } +} + +module.exports = { + reqBody, + queryParams, + validBaseUrl, +}; diff --git a/collector/utils/logger/index.js b/collector/utils/logger/index.js new file mode 100644 index 0000000000000000000000000000000000000000..a0eddeca0e81b4b958e8ad8b079f8ef96a8f9329 --- /dev/null +++ b/collector/utils/logger/index.js @@ -0,0 +1,68 @@ +const winston = require("winston"); + +class Logger { + logger = console; + static _instance; + constructor() { + if (Logger._instance) return Logger._instance; + this.logger = + process.env.NODE_ENV === "production" ? this.getWinstonLogger() : console; + Logger._instance = this; + } + + getWinstonLogger() { + const logger = winston.createLogger({ + level: "info", + defaultMeta: { service: "collector" }, + transports: [ + new winston.transports.Console({ + format: winston.format.combine( + winston.format.colorize(), + winston.format.printf( + ({ level, message, service, origin = "" }) => { + return `\x1b[36m[${service}]\x1b[0m${ + origin ? `\x1b[33m[${origin}]\x1b[0m` : "" + } ${level}: ${message}`; + } + ) + ), + }), + ], + }); + + function formatArgs(args) { + return args + .map((arg) => { + if (arg instanceof Error) { + return arg.stack; // If argument is an Error object, return its stack trace + } else if (typeof arg === "object") { + return JSON.stringify(arg); // Convert objects to JSON string + } else { + return arg; // Otherwise, return as-is + } + }) + .join(" "); + } + + console.log = function (...args) { + logger.info(formatArgs(args)); + }; + console.error = function (...args) { + logger.error(formatArgs(args)); + }; + console.info = function (...args) { + logger.warn(formatArgs(args)); + }; + return logger; + } +} + +/** + * Sets and overrides Console methods for logging when called. + * This is a singleton method and will not create multiple loggers. + * @returns {winston.Logger | console} - instantiated logger interface. + */ +function setLogger() { + return new Logger().logger; +} +module.exports = setLogger; diff --git a/collector/utils/runtimeSettings/index.js b/collector/utils/runtimeSettings/index.js new file mode 100644 index 0000000000000000000000000000000000000000..da60a1234328906aa25bacebc3129fe4707575c2 --- /dev/null +++ b/collector/utils/runtimeSettings/index.js @@ -0,0 +1,93 @@ +const { reqBody } = require("../http"); + +/** + * Runtime settings are used to configure the collector per-request. + * These settings are persisted across requests, but can be overridden per-request. + * + * The settings are passed in the request body via `options.runtimeSettings` + * which is set in the backend #attachOptions function in CollectorApi. + * + * We do this so that the collector and backend can share the same ENV variables + * but only pass the relevant settings to the collector per-request and be able to + * access them across the collector via a single instance of RuntimeSettings. + * + * TODO: We may want to set all options passed from backend to collector here, + * but for now - we are only setting the runtime settings specifically for backwards + * compatibility with existing CollectorApi usage. + */ +class RuntimeSettings { + static _instance = null; + settings = {}; + + // Any settings here will be persisted across requests + // and must be explicitly defined here. + settingConfigs = { + allowAnyIp: { + default: false, + // Value must be explicitly "true" or "false" as a string + validate: (value) => String(value) === "true", + }, + browserLaunchArgs: { + default: [], + validate: (value) => { + let args = []; + if (Array.isArray(value)) args = value.map((arg) => String(arg.trim())); + if (typeof value === "string") + args = value.split(",").map((arg) => arg.trim()); + return args; + }, + }, + }; + + constructor() { + if (RuntimeSettings._instance) return RuntimeSettings._instance; + RuntimeSettings._instance = this; + return this; + } + + /** + * Parse the runtime settings from the request body options body + * see #attachOptions https://github.com/Mintplex-Labs/anything-llm/blob/ebf112007e0d579af3d2b43569db95bdfc59074b/server/utils/collectorApi/index.js#L18 + * @param {import('express').Request} request + * @returns {void} + */ + parseOptionsFromRequest(request = {}) { + const options = reqBody(request)?.options?.runtimeSettings || {}; + for (const [key, value] of Object.entries(options)) { + if (!this.settingConfigs.hasOwnProperty(key)) continue; + this.set(key, value); + } + return; + } + + /** + * Get a runtime setting + * - Will throw an error if the setting requested is not a supported runtime setting key + * - Will return the default value if the setting requested is not set at all + * @param {string} key + * @returns {any} + */ + get(key) { + if (!this.settingConfigs[key]) + throw new Error(`Invalid runtime setting: ${key}`); + return this.settings.hasOwnProperty(key) + ? this.settings[key] + : this.settingConfigs[key].default; + } + + /** + * Set a runtime setting + * - Will throw an error if the setting requested is not a supported runtime setting key + * - Will validate the value against the setting's validate function + * @param {string} key + * @param {any} value + * @returns {void} + */ + set(key, value = null) { + if (!this.settingConfigs[key]) + throw new Error(`Invalid runtime setting: ${key}`); + this.settings[key] = this.settingConfigs[key].validate(value); + } +} + +module.exports = RuntimeSettings; diff --git a/collector/utils/tokenizer/index.js b/collector/utils/tokenizer/index.js new file mode 100644 index 0000000000000000000000000000000000000000..2086be2574b55f18692b85c6fb31f75099ea8177 --- /dev/null +++ b/collector/utils/tokenizer/index.js @@ -0,0 +1,66 @@ +const { getEncoding } = require("js-tiktoken"); + +class TikTokenTokenizer { + static MAX_KB_ESTIMATE = 10; + static DIVISOR = 8; + + constructor() { + if (TikTokenTokenizer.instance) { + this.log( + "Singleton instance already exists. Returning existing instance." + ); + return TikTokenTokenizer.instance; + } + + this.encoder = getEncoding("cl100k_base"); + TikTokenTokenizer.instance = this; + this.log("Initialized new TikTokenTokenizer instance."); + } + + log(text, ...args) { + console.log(`\x1b[35m[TikTokenTokenizer]\x1b[0m ${text}`, ...args); + } + + /** + * Check if the input is too long to encode + * this is more of a rough estimate and a sanity check to prevent + * CPU issues from encoding too large of strings + * Assumes 1 character = 2 bytes in JS + * @param {string} input + * @returns {boolean} + */ + #isTooLong(input) { + const bytesEstimate = input.length * 2; + const kbEstimate = Math.floor(bytesEstimate / 1024); + return kbEstimate >= TikTokenTokenizer.MAX_KB_ESTIMATE; + } + + /** + * Encode a string into tokens for rough token count estimation. + * @param {string} input + * @returns {number} + */ + tokenizeString(input = "") { + try { + if (this.#isTooLong(input)) { + this.log("Input will take too long to encode - estimating"); + return Math.ceil(input.length / TikTokenTokenizer.DIVISOR); + } + + return this.encoder.encode(input).length; + } catch (e) { + this.log("Could not tokenize string! Estimating...", e.message, e.stack); + return Math.ceil(input?.length / TikTokenTokenizer.DIVISOR) || 0; + } + } +} + +const tokenizer = new TikTokenTokenizer(); +module.exports = { + /** + * Encode a string into tokens for rough token count estimation. + * @param {string} input + * @returns {number} + */ + tokenizeString: (input) => tokenizer.tokenizeString(input), +}; diff --git a/collector/utils/url/index.js b/collector/utils/url/index.js new file mode 100644 index 0000000000000000000000000000000000000000..d7d633128f5be45b741db366411c06a573f28973 --- /dev/null +++ b/collector/utils/url/index.js @@ -0,0 +1,73 @@ +const RuntimeSettings = require("../runtimeSettings"); +/** ATTN: SECURITY RESEARCHERS + * To Security researchers about to submit an SSRF report CVE - please don't. + * We are aware that the code below is does not defend against any of the thousands of ways + * you can map a hostname to another IP via tunneling, hosts editing, etc. The code below does not have intention of blocking this + * and is simply to prevent the user from accidentally putting in non-valid websites, which is all this protects + * since _all urls must be submitted by the user anyway_ and cannot be done with authentication and manager or admin roles. + * If an attacker has those roles then the system is already vulnerable and this is not a primary concern. + * + * We have gotten this report may times, marked them as duplicate or information and continue to get them. We communicate + * already that deployment (and security) of an instance is on the deployer and system admin deploying it. This would include + * isolation, firewalls, and the general security of the instance. + */ + +const VALID_PROTOCOLS = ["https:", "http:"]; +const INVALID_OCTETS = [192, 172, 10, 127]; +const runtimeSettings = new RuntimeSettings(); + +/** + * If an ip address is passed in the user is attempting to collector some internal service running on internal/private IP. + * This is not a security feature and simply just prevents the user from accidentally entering invalid IP addresses. + * Can be bypassed via COLLECTOR_ALLOW_ANY_IP environment variable. + * @param {URL} param0 + * @param {URL['hostname']} param0.hostname + * @returns {boolean} + */ +function isInvalidIp({ hostname }) { + if (runtimeSettings.get("allowAnyIp")) { + console.log( + "\x1b[33mURL IP local address restrictions have been disabled by administrator!\x1b[0m" + ); + return false; + } + + const IPRegex = new RegExp( + /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/gi + ); + + // Not an IP address at all - passthrough + if (!IPRegex.test(hostname)) return false; + const [octetOne, ..._rest] = hostname.split("."); + + // If fails to validate to number - abort and return as invalid. + if (isNaN(Number(octetOne))) return true; + + // Allow localhost loopback and 0.0.0.0 for scraping convenience + // for locally hosted services or websites + if (["127.0.0.1", "0.0.0.0"].includes(hostname)) return false; + + return INVALID_OCTETS.includes(Number(octetOne)); +} + +/** + * Validates a URL + * - Checks the URL forms a valid URL + * - Checks the URL is at least HTTP(S) + * - Checks the URL is not an internal IP - can be bypassed via COLLECTOR_ALLOW_ANY_IP + * @param {string} url + * @returns {boolean} + */ +function validURL(url) { + try { + const destination = new URL(url); + if (!VALID_PROTOCOLS.includes(destination.protocol)) return false; + if (isInvalidIp(destination)) return false; + return true; + } catch {} + return false; +} + +module.exports = { + validURL, +}; diff --git a/collector/yarn.lock b/collector/yarn.lock new file mode 100644 index 0000000000000000000000000000000000000000..c14b76a2c959d29c5be47a435ad2103d32cd8e61 --- /dev/null +++ b/collector/yarn.lock @@ -0,0 +1,3871 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@anthropic-ai/sdk@^0.9.1": + version "0.9.1" + resolved "https://registry.yarnpkg.com/@anthropic-ai/sdk/-/sdk-0.9.1.tgz#b2d2b7bf05c90dce502c9a2e869066870f69ba88" + integrity sha512-wa1meQ2WSfoY8Uor3EdrJq0jTiZJoKoSii2ZVWRY1oN4Tlr5s59pADg9T79FTbPe1/se5c3pBeZgJL63wmuoBA== + dependencies: + "@types/node" "^18.11.18" + "@types/node-fetch" "^2.6.4" + abort-controller "^3.0.0" + agentkeepalive "^4.2.1" + digest-fetch "^1.3.0" + form-data-encoder "1.7.2" + formdata-node "^4.3.2" + node-fetch "^2.6.7" + web-streams-polyfill "^3.2.1" + +"@babel/code-frame@^7.0.0": + version "7.24.2" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.24.2.tgz#718b4b19841809a58b29b68cde80bc5e1aa6d9ae" + integrity sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ== + dependencies: + "@babel/highlight" "^7.24.2" + picocolors "^1.0.0" + +"@babel/helper-validator-identifier@^7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.5.tgz#918b1a7fa23056603506370089bd990d8720db62" + integrity sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA== + +"@babel/highlight@^7.24.2": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.24.5.tgz#bc0613f98e1dd0720e99b2a9ee3760194a704b6e" + integrity sha512-8lLmua6AVh/8SLJRRVD6V8p73Hir9w5mJrhE+IPpILG31KKlI9iz5zmBYKcWPS59qSfgP9RaSBQSHHE81WKuEw== + dependencies: + "@babel/helper-validator-identifier" "^7.24.5" + chalk "^2.4.2" + js-tokens "^4.0.0" + picocolors "^1.0.0" + +"@colors/colors@1.6.0", "@colors/colors@^1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.6.0.tgz#ec6cd237440700bc23ca23087f513c75508958b0" + integrity sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA== + +"@dabh/diagnostics@^2.0.2": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@dabh/diagnostics/-/diagnostics-2.0.3.tgz#7f7e97ee9a725dffc7808d93668cc984e1dc477a" + integrity sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA== + dependencies: + colorspace "1.1.x" + enabled "2.0.x" + kuler "^2.0.0" + +"@emnapi/runtime@^1.2.0": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@emnapi/runtime/-/runtime-1.3.1.tgz#0fcaa575afc31f455fd33534c19381cfce6c6f60" + integrity sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw== + dependencies: + tslib "^2.4.0" + +"@fastify/busboy@^2.0.0": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-2.1.1.tgz#b9da6a878a371829a0502c9b6c1c143ef6663f4d" + integrity sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA== + +"@huggingface/jinja@^0.2.2": + version "0.2.2" + resolved "https://registry.yarnpkg.com/@huggingface/jinja/-/jinja-0.2.2.tgz#faeb205a9d6995089bef52655ddd8245d3190627" + integrity sha512-/KPde26khDUIPkTGU82jdtTW9UAuvUTumCAbFs/7giR0SxsvZC4hru51PBvpijH6BVkHcROcvZM/lpy5h1jRRA== + +"@img/sharp-darwin-arm64@0.33.5": + version "0.33.5" + resolved "https://registry.yarnpkg.com/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz#ef5b5a07862805f1e8145a377c8ba6e98813ca08" + integrity sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ== + optionalDependencies: + "@img/sharp-libvips-darwin-arm64" "1.0.4" + +"@img/sharp-darwin-x64@0.33.5": + version "0.33.5" + resolved "https://registry.yarnpkg.com/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz#e03d3451cd9e664faa72948cc70a403ea4063d61" + integrity sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q== + optionalDependencies: + "@img/sharp-libvips-darwin-x64" "1.0.4" + +"@img/sharp-libvips-darwin-arm64@1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz#447c5026700c01a993c7804eb8af5f6e9868c07f" + integrity sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg== + +"@img/sharp-libvips-darwin-x64@1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz#e0456f8f7c623f9dbfbdc77383caa72281d86062" + integrity sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ== + +"@img/sharp-libvips-linux-arm64@1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz#979b1c66c9a91f7ff2893556ef267f90ebe51704" + integrity sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA== + +"@img/sharp-libvips-linux-arm@1.0.5": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz#99f922d4e15216ec205dcb6891b721bfd2884197" + integrity sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g== + +"@img/sharp-libvips-linux-s390x@1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz#f8a5eb1f374a082f72b3f45e2fb25b8118a8a5ce" + integrity sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA== + +"@img/sharp-libvips-linux-x64@1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz#d4c4619cdd157774906e15770ee119931c7ef5e0" + integrity sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw== + +"@img/sharp-libvips-linuxmusl-arm64@1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz#166778da0f48dd2bded1fa3033cee6b588f0d5d5" + integrity sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA== + +"@img/sharp-libvips-linuxmusl-x64@1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz#93794e4d7720b077fcad3e02982f2f1c246751ff" + integrity sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw== + +"@img/sharp-linux-arm64@0.33.5": + version "0.33.5" + resolved "https://registry.yarnpkg.com/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz#edb0697e7a8279c9fc829a60fc35644c4839bb22" + integrity sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA== + optionalDependencies: + "@img/sharp-libvips-linux-arm64" "1.0.4" + +"@img/sharp-linux-arm@0.33.5": + version "0.33.5" + resolved "https://registry.yarnpkg.com/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz#422c1a352e7b5832842577dc51602bcd5b6f5eff" + integrity sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ== + optionalDependencies: + "@img/sharp-libvips-linux-arm" "1.0.5" + +"@img/sharp-linux-s390x@0.33.5": + version "0.33.5" + resolved "https://registry.yarnpkg.com/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz#f5c077926b48e97e4a04d004dfaf175972059667" + integrity sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q== + optionalDependencies: + "@img/sharp-libvips-linux-s390x" "1.0.4" + +"@img/sharp-linux-x64@0.33.5": + version "0.33.5" + resolved "https://registry.yarnpkg.com/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz#d806e0afd71ae6775cc87f0da8f2d03a7c2209cb" + integrity sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA== + optionalDependencies: + "@img/sharp-libvips-linux-x64" "1.0.4" + +"@img/sharp-linuxmusl-arm64@0.33.5": + version "0.33.5" + resolved "https://registry.yarnpkg.com/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz#252975b915894fb315af5deea174651e208d3d6b" + integrity sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g== + optionalDependencies: + "@img/sharp-libvips-linuxmusl-arm64" "1.0.4" + +"@img/sharp-linuxmusl-x64@0.33.5": + version "0.33.5" + resolved "https://registry.yarnpkg.com/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz#3f4609ac5d8ef8ec7dadee80b560961a60fd4f48" + integrity sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw== + optionalDependencies: + "@img/sharp-libvips-linuxmusl-x64" "1.0.4" + +"@img/sharp-wasm32@0.33.5": + version "0.33.5" + resolved "https://registry.yarnpkg.com/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz#6f44f3283069d935bb5ca5813153572f3e6f61a1" + integrity sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg== + dependencies: + "@emnapi/runtime" "^1.2.0" + +"@img/sharp-win32-ia32@0.33.5": + version "0.33.5" + resolved "https://registry.yarnpkg.com/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz#1a0c839a40c5351e9885628c85f2e5dfd02b52a9" + integrity sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ== + +"@img/sharp-win32-x64@0.33.5": + version "0.33.5" + resolved "https://registry.yarnpkg.com/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz#56f00962ff0c4e0eb93d34a047d29fa995e3e342" + integrity sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg== + +"@langchain/community@^0.2.23": + version "0.2.23" + resolved "https://registry.yarnpkg.com/@langchain/community/-/community-0.2.23.tgz#20560e107bcc8432c42e499f1b9292d41a3732f2" + integrity sha512-p1n/zZ1F+O5l51RzeoUeJyhpzq6Wp11tkqKOj8oThKOQJgLhO7q6iFIvmKThzL7mZCNNuPM5r1OPnU4wO6iF/A== + dependencies: + "@langchain/core" ">=0.2.16 <0.3.0" + "@langchain/openai" ">=0.1.0 <0.3.0" + binary-extensions "^2.2.0" + expr-eval "^2.0.2" + flat "^5.0.2" + js-yaml "^4.1.0" + langchain "~0.2.3" + langsmith "~0.1.30" + uuid "^10.0.0" + zod "^3.22.3" + zod-to-json-schema "^3.22.5" + +"@langchain/community@~0.0.47": + version "0.0.53" + resolved "https://registry.yarnpkg.com/@langchain/community/-/community-0.0.53.tgz#a9aaedffa0ed2977e8d302d74e9f90a49a6da037" + integrity sha512-iFqZPt4MRssGYsQoKSXWJQaYTZCC7WNuilp2JCCs3wKmJK3l6mR0eV+PDrnT+TaDHUVxt/b0rwgM0sOiy0j2jA== + dependencies: + "@langchain/core" "~0.1.60" + "@langchain/openai" "~0.0.28" + expr-eval "^2.0.2" + flat "^5.0.2" + langsmith "~0.1.1" + uuid "^9.0.0" + zod "^3.22.3" + zod-to-json-schema "^3.22.5" + +"@langchain/core@>=0.2.11 <0.3.0", "@langchain/core@>=0.2.16 <0.3.0": + version "0.2.20" + resolved "https://registry.yarnpkg.com/@langchain/core/-/core-0.2.20.tgz#5115781b0a86db3ce4b697e473405892c09621ca" + integrity sha512-WPBjrzOj79/yqjloDUIw1GDhuRQfHis07TyyDj+qS81nHh0svSasetKcqAZ3L5JoPcBmEL7rRBtM+OcyC3mLVg== + dependencies: + ansi-styles "^5.0.0" + camelcase "6" + decamelize "1.2.0" + js-tiktoken "^1.0.12" + langsmith "~0.1.39" + mustache "^4.2.0" + p-queue "^6.6.2" + p-retry "4" + uuid "^10.0.0" + zod "^3.22.4" + zod-to-json-schema "^3.22.3" + +"@langchain/core@~0.1", "@langchain/core@~0.1.56", "@langchain/core@~0.1.60": + version "0.1.61" + resolved "https://registry.yarnpkg.com/@langchain/core/-/core-0.1.61.tgz#9313363e04f1c6981a938b2909c44ce6fceb2736" + integrity sha512-C8OkAly+ugvXsL8TACCmFv9WTTcT4gvQaG6NbrXCOzibBCywfxxcTqEMOyg3zIKpxHEmR0DHqh0OiJRHocnsCg== + dependencies: + ansi-styles "^5.0.0" + camelcase "6" + decamelize "1.2.0" + js-tiktoken "^1.0.8" + langsmith "~0.1.7" + ml-distance "^4.0.0" + mustache "^4.2.0" + p-queue "^6.6.2" + p-retry "4" + uuid "^9.0.0" + zod "^3.22.4" + zod-to-json-schema "^3.22.3" + +"@langchain/openai@>=0.1.0 <0.3.0": + version "0.2.5" + resolved "https://registry.yarnpkg.com/@langchain/openai/-/openai-0.2.5.tgz#e85b983986a7415ea743d4c854bb0674134334d4" + integrity sha512-gQXS5VBFyAco0jgSnUVan6fYVSIxlffmDaeDGpXrAmz2nQPgiN/h24KYOt2NOZ1zRheRzRuO/CfRagMhyVUaFA== + dependencies: + "@langchain/core" ">=0.2.16 <0.3.0" + js-tiktoken "^1.0.12" + openai "^4.49.1" + zod "^3.22.4" + zod-to-json-schema "^3.22.3" + +"@langchain/openai@~0.0.28": + version "0.0.28" + resolved "https://registry.yarnpkg.com/@langchain/openai/-/openai-0.0.28.tgz#afaeec61b44816935db9ae937496c964c81ab571" + integrity sha512-2s1RA3/eAnz4ahdzsMPBna9hfAqpFNlWdHiPxVGZ5yrhXsbLWWoPcF+22LCk9t0HJKtazi2GCIWc0HVXH9Abig== + dependencies: + "@langchain/core" "~0.1.56" + js-tiktoken "^1.0.7" + openai "^4.32.1" + zod "^3.22.4" + zod-to-json-schema "^3.22.3" + +"@langchain/textsplitters@~0.0.0": + version "0.0.0" + resolved "https://registry.yarnpkg.com/@langchain/textsplitters/-/textsplitters-0.0.0.tgz#5fe05fcd86ad7f1b4766afacda482cba98a3d35d" + integrity sha512-3hPesWomnmVeYMppEGYbyv0v/sRUugUdlFBNn9m1ueJYHAIKbvCErkWxNUH3guyKKYgJVrkvZoQxcd9faucSaw== + dependencies: + "@langchain/core" "~0.1" + js-tiktoken "^1.0.11" + +"@mapbox/node-pre-gyp@^1.0.11": + version "1.0.11" + resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz#417db42b7f5323d79e93b34a6d7a2a12c0df43fa" + integrity sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ== + dependencies: + detect-libc "^2.0.0" + https-proxy-agent "^5.0.0" + make-dir "^3.1.0" + node-fetch "^2.6.7" + nopt "^5.0.0" + npmlog "^5.0.1" + rimraf "^3.0.2" + semver "^7.3.5" + tar "^6.1.11" + +"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" + integrity sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ== + +"@protobufjs/base64@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" + integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== + +"@protobufjs/codegen@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" + integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== + +"@protobufjs/eventemitter@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" + integrity sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q== + +"@protobufjs/fetch@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" + integrity sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ== + dependencies: + "@protobufjs/aspromise" "^1.1.1" + "@protobufjs/inquire" "^1.1.0" + +"@protobufjs/float@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" + integrity sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ== + +"@protobufjs/inquire@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" + integrity sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q== + +"@protobufjs/path@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" + integrity sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA== + +"@protobufjs/pool@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" + integrity sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw== + +"@protobufjs/utf8@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" + integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw== + +"@puppeteer/browsers@1.8.0": + version "1.8.0" + resolved "https://registry.yarnpkg.com/@puppeteer/browsers/-/browsers-1.8.0.tgz#fb6ee61de15e7f0e67737aea9f9bab1512dbd7d8" + integrity sha512-TkRHIV6k2D8OlUe8RtG+5jgOF/H98Myx0M6AOafC8DdNVOFiBSFa5cpRDtpm8LXOa9sVwe0+e6Q3FC56X/DZfg== + dependencies: + debug "4.3.4" + extract-zip "2.0.1" + progress "2.0.3" + proxy-agent "6.3.1" + tar-fs "3.0.4" + unbzip2-stream "1.4.3" + yargs "17.7.2" + +"@selderee/plugin-htmlparser2@^0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@selderee/plugin-htmlparser2/-/plugin-htmlparser2-0.11.0.tgz#d5b5e29a7ba6d3958a1972c7be16f4b2c188c517" + integrity sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ== + dependencies: + domhandler "^5.0.3" + selderee "^0.11.0" + +"@tokenizer/token@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@tokenizer/token/-/token-0.3.0.tgz#fe98a93fe789247e998c75e74e9c7c63217aa276" + integrity sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A== + +"@tootallnate/quickjs-emscripten@^0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz#db4ecfd499a9765ab24002c3b696d02e6d32a12c" + integrity sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA== + +"@types/long@^4.0.1": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.2.tgz#b74129719fc8d11c01868010082d483b7545591a" + integrity sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA== + +"@types/mailparser@^3.0.0": + version "3.4.4" + resolved "https://registry.yarnpkg.com/@types/mailparser/-/mailparser-3.4.4.tgz#0bd71e205573b9dd9a445e10a8b8cb0e45420998" + integrity sha512-C6Znp2QVS25JqtuPyxj38Qh+QoFcLycdxsvcc6IZCGekhaMBzbdTXzwGzhGoYb3TfKu8IRCNV0sV1o3Od97cEQ== + dependencies: + "@types/node" "*" + iconv-lite "^0.6.3" + +"@types/node-fetch@^2.6.4": + version "2.6.11" + resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.11.tgz#9b39b78665dae0e82a08f02f4967d62c66f95d24" + integrity sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g== + dependencies: + "@types/node" "*" + form-data "^4.0.0" + +"@types/node@*", "@types/node@>=13.7.0": + version "20.12.7" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.12.7.tgz#04080362fa3dd6c5822061aa3124f5c152cff384" + integrity sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg== + dependencies: + undici-types "~5.26.4" + +"@types/node@^18.11.18": + version "18.19.31" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.31.tgz#b7d4a00f7cb826b60a543cebdbda5d189aaecdcd" + integrity sha512-ArgCD39YpyyrtFKIqMDvjz79jto5fcI/SVUs2HwB+f0dAzq68yqOdyaSivLiLugSziTpNXLQrVb7RZFmdZzbhA== + dependencies: + undici-types "~5.26.4" + +"@types/retry@0.12.0": + version "0.12.0" + resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d" + integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== + +"@types/triple-beam@^1.3.2": + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/triple-beam/-/triple-beam-1.3.5.tgz#74fef9ffbaa198eb8b588be029f38b00299caa2c" + integrity sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw== + +"@types/uuid@^9.0.1": + version "9.0.8" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.8.tgz#7545ba4fc3c003d6c756f651f3bf163d8f0f29ba" + integrity sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA== + +"@types/yauzl@^2.9.1": + version "2.10.3" + resolved "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.10.3.tgz#e9b2808b4f109504a03cda958259876f61017999" + integrity sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q== + dependencies: + "@types/node" "*" + +"@xenova/transformers@^2.14.0": + version "2.17.2" + resolved "https://registry.yarnpkg.com/@xenova/transformers/-/transformers-2.17.2.tgz#7448d73b90f67bced66f39fe2dd656adc891fde5" + integrity sha512-lZmHqzrVIkSvZdKZEx7IYY51TK0WDrC8eR0c5IMnBsO8di8are1zzw8BlLhyO2TklZKLN5UffNGs1IJwT6oOqQ== + dependencies: + "@huggingface/jinja" "^0.2.2" + onnxruntime-web "1.14.0" + sharp "^0.32.0" + optionalDependencies: + onnxruntime-node "1.14.0" + +"@xmldom/xmldom@^0.8.10", "@xmldom/xmldom@^0.8.6": + version "0.8.10" + resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.8.10.tgz#a1337ca426aa61cef9fe15b5b28e340a72f6fa99" + integrity sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw== + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + +abort-controller@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" + integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== + dependencies: + event-target-shim "^5.0.0" + +accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + +acorn@^8.8.0: + version "8.11.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a" + integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== + +adm-zip@^0.5.10: + version "0.5.12" + resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.5.12.tgz#87786328e91d54b37358d8a50f954c4cd73ba60b" + integrity sha512-6TVU49mK6KZb4qG6xWaaM4C7sA/sgUMLy/JYMOzkcp3BvVLpW0fXDFQiIzAuxFCt/2+xD7fNIiPFAoLZPhVNLQ== + +agent-base@6: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + +agent-base@^7.0.2, agent-base@^7.1.0, agent-base@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.1.tgz#bdbded7dfb096b751a2a087eeeb9664725b2e317" + integrity sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA== + dependencies: + debug "^4.3.4" + +agentkeepalive@^4.2.1: + version "4.5.0" + resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.5.0.tgz#2673ad1389b3c418c5a20c5d7364f93ca04be923" + integrity sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew== + dependencies: + humanize-ms "^1.2.1" + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +ansi-styles@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" + integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== + +anymatch@~3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +"aproba@^1.0.3 || ^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" + integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== + +are-we-there-yet@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz#372e0e7bd279d8e94c653aaa1f67200884bf3e1c" + integrity sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw== + dependencies: + delegates "^1.0.0" + readable-stream "^3.6.0" + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +argparse@~1.0.3: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== + +array-hyper-unique@^2.1.4: + version "2.1.6" + resolved "https://registry.yarnpkg.com/array-hyper-unique/-/array-hyper-unique-2.1.6.tgz#429412fd63b7bd7c920f6cdbf60d1dd292855b2e" + integrity sha512-BdlHRqjKSYs88WFaVNVEc6Kv8ln/FdzCKPbcDPuWs4/EXkQFhnjc8TyR7hnPxRjcjo5LKOhUMGUWpAqRgeJvpA== + dependencies: + deep-eql "= 4.0.0" + lodash "^4.17.21" + +ast-types@^0.13.4: + version "0.13.4" + resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.13.4.tgz#ee0d77b343263965ecc3fb62da16e7222b2b6782" + integrity sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w== + dependencies: + tslib "^2.0.1" + +async@>=0.2.9, async@^3.2.3: + version "3.2.5" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.5.tgz#ebd52a8fdaf7a2289a24df399f8d8485c8a46b66" + integrity sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg== + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + +b4a@^1.6.4: + version "1.6.6" + resolved "https://registry.yarnpkg.com/b4a/-/b4a-1.6.6.tgz#a4cc349a3851987c3c4ac2d7785c18744f6da9ba" + integrity sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg== + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +bare-events@^2.0.0, bare-events@^2.2.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/bare-events/-/bare-events-2.2.2.tgz#a98a41841f98b2efe7ecc5c5468814469b018078" + integrity sha512-h7z00dWdG0PYOQEvChhOSWvOfkIKsdZGkWr083FgN/HyoQuebSew/cgirYqh9SCuy/hRvxc5Vy6Fw8xAmYHLkQ== + +bare-fs@^2.1.1: + version "2.3.0" + resolved "https://registry.yarnpkg.com/bare-fs/-/bare-fs-2.3.0.tgz#0872f8e33cf291c9fd527d827154f156a298d402" + integrity sha512-TNFqa1B4N99pds2a5NYHR15o0ZpdNKbAeKTE/+G6ED/UeOavv8RY3dr/Fu99HW3zU3pXpo2kDNO8Sjsm2esfOw== + dependencies: + bare-events "^2.0.0" + bare-path "^2.0.0" + bare-stream "^1.0.0" + +bare-os@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/bare-os/-/bare-os-2.3.0.tgz#718e680b139effff0624a7421c098e7a2c2d63da" + integrity sha512-oPb8oMM1xZbhRQBngTgpcQ5gXw6kjOaRsSWsIeNyRxGed2w/ARyP7ScBYpWR1qfX2E5rS3gBw6OWcSQo+s+kUg== + +bare-path@^2.0.0, bare-path@^2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/bare-path/-/bare-path-2.1.2.tgz#7a0940d34ebe65f7e179fa61ed8d49d9dc151d67" + integrity sha512-o7KSt4prEphWUHa3QUwCxUI00R86VdjiuxmJK0iNVDHYPGo+HsDaVCnqCmPbf/MiW1ok8F4p3m8RTHlWk8K2ig== + dependencies: + bare-os "^2.1.0" + +bare-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/bare-stream/-/bare-stream-1.0.0.tgz#25c3e56198d922187320c3f8c52d75c4051178b4" + integrity sha512-KhNUoDL40iP4gFaLSsoGE479t0jHijfYdIcxRn/XtezA2BaUD0NRf/JGRpsMq6dMNM+SrCrB0YSSo/5wBY4rOQ== + dependencies: + streamx "^2.16.1" + +base-64@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/base-64/-/base-64-0.1.0.tgz#780a99c84e7d600260361511c4877613bf24f6bb" + integrity sha512-Y5gU45svrR5tI2Vt/X9GPd3L0HNIKzGu202EjxrXMpuc2V2CiKgemAbUUsqYmZJvPtCXoUKjNZwBJzsNScUbXA== + +base64-js@^1.3.1, base64-js@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + +basic-ftp@^5.0.2: + version "5.0.5" + resolved "https://registry.yarnpkg.com/basic-ftp/-/basic-ftp-5.0.5.tgz#14a474f5fffecca1f4f406f1c26b18f800225ac0" + integrity sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg== + +bcrypt@^5.1.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/bcrypt/-/bcrypt-5.1.1.tgz#0f732c6dcb4e12e5b70a25e326a72965879ba6e2" + integrity sha512-AGBHOG5hPYZ5Xl9KXzU5iKq9516yEmvCKDg3ecP5kX2aB6UqTeXZxk2ELnDgDm6BQSMlLt9rDB4LoSMx0rYwww== + dependencies: + "@mapbox/node-pre-gyp" "^1.0.11" + node-addon-api "^5.0.0" + +binary-extensions@^2.0.0, binary-extensions@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522" + integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== + +binary-search@^1.3.5: + version "1.3.6" + resolved "https://registry.yarnpkg.com/binary-search/-/binary-search-1.3.6.tgz#e32426016a0c5092f0f3598836a1c7da3560565c" + integrity sha512-nbE1WxOTTrUWIfsfZ4aHGYu5DOuNkbxGokjV6Z2kxfJK3uaAb8zNK1muzOeipoLHZjInT4Br88BHpzevc681xA== + +bl@^1.0.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.3.tgz#1e8dd80142eac80d7158c9dccc047fb620e035e7" + integrity sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww== + dependencies: + readable-stream "^2.3.5" + safe-buffer "^5.1.1" + +bl@^4.0.3: + version "4.1.0" + resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" + integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== + dependencies: + buffer "^5.5.0" + inherits "^2.0.4" + readable-stream "^3.4.0" + +bluebird@^3.7.2: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + +bluebird@~3.4.0: + version "3.4.7" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.4.7.tgz#f72d760be09b7f76d08ed8fae98b289a8d05fab3" + integrity sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA== + +bmp-js@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/bmp-js/-/bmp-js-0.1.0.tgz#e05a63f796a6c1ff25f4771ec7adadc148c07233" + integrity sha512-vHdS19CnY3hwiNdkaqk93DvjVLfbEcI8mys4UjuWrlX1haDmroo8o4xCzh4wD6DGV6HxRCyauwhHRqMTfERtjw== + +body-parser@1.20.2, body-parser@^1.20.2: + version "1.20.2" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd" + integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA== + dependencies: + bytes "3.1.2" + content-type "~1.0.5" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.11.0" + raw-body "2.5.2" + type-is "~1.6.18" + unpipe "1.0.0" + +boolbase@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +buffer-alloc-unsafe@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" + integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== + +buffer-alloc@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" + integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== + dependencies: + buffer-alloc-unsafe "^1.1.0" + buffer-fill "^1.0.0" + +buffer-crc32@~0.2.3: + version "0.2.13" + resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== + +buffer-fill@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" + integrity sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ== + +buffer@^5.2.1, buffer@^5.5.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + +call-bind@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" + integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + set-function-length "^1.2.1" + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camelcase@6: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + +chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +charenc@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" + integrity sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA== + +chokidar@^3.5.2: + version "3.6.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" + integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +chownr@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + +chownr@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" + integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== + +chromium-bidi@0.4.33: + version "0.4.33" + resolved "https://registry.yarnpkg.com/chromium-bidi/-/chromium-bidi-0.4.33.tgz#9a9aba5a5b07118c8e7d6405f8ee79f47418dd1d" + integrity sha512-IxoFM5WGQOIAd95qrSXzJUv4eXIrh+RvU3rwwqIiwYuvfE7U/Llj4fejbsJnjJMUYCuGtVQsY2gv7oGl4aTNSQ== + dependencies: + mitt "3.0.1" + urlpattern-polyfill "9.0.0" + +cliui@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" + integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.1" + wrap-ansi "^7.0.0" + +color-convert@^1.9.0, color-convert@^1.9.3: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + +color-name@^1.0.0, color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +color-string@^1.6.0, color-string@^1.9.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.9.1.tgz#4467f9146f036f855b764dfb5bf8582bf342c7a4" + integrity sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg== + dependencies: + color-name "^1.0.0" + simple-swizzle "^0.2.2" + +color-support@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" + integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== + +color@^3.1.3: + version "3.2.1" + resolved "https://registry.yarnpkg.com/color/-/color-3.2.1.tgz#3544dc198caf4490c3ecc9a790b54fe9ff45e164" + integrity sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA== + dependencies: + color-convert "^1.9.3" + color-string "^1.6.0" + +color@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/color/-/color-4.2.3.tgz#d781ecb5e57224ee43ea9627560107c0e0c6463a" + integrity sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A== + dependencies: + color-convert "^2.0.1" + color-string "^1.9.0" + +colorspace@1.1.x: + version "1.1.4" + resolved "https://registry.yarnpkg.com/colorspace/-/colorspace-1.1.4.tgz#8d442d1186152f60453bf8070cd66eb364e59243" + integrity sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w== + dependencies: + color "^3.1.3" + text-hex "1.0.x" + +combined-stream@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +commander@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" + integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== + +commander@^2.8.1: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +console-control-strings@^1.0.0, console-control-strings@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== + +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-type@~1.0.4, content-type@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" + integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== + +cookie@0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051" + integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw== + +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + +cors@^2.8.5: + version "2.8.5" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" + integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== + dependencies: + object-assign "^4" + vary "^1" + +cosmiconfig@8.3.6: + version "8.3.6" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.3.6.tgz#060a2b871d66dba6c8538ea1118ba1ac16f5fae3" + integrity sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA== + dependencies: + import-fresh "^3.3.0" + js-yaml "^4.1.0" + parse-json "^5.2.0" + path-type "^4.0.0" + +crlf-normalize@^1.0.19: + version "1.0.20" + resolved "https://registry.yarnpkg.com/crlf-normalize/-/crlf-normalize-1.0.20.tgz#0b3105d3de807bce8a7599113235d725fe9361a8" + integrity sha512-h/rBerTd3YHQGfv7tNT25mfhWvRq2BBLCZZ80GFarFxf6HQGbpW6iqDL3N+HBLpjLfAdcBXfWAzVlLfHkRUQBQ== + dependencies: + ts-type ">=2" + +cross-env@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf" + integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw== + dependencies: + cross-spawn "^7.0.1" + +cross-fetch@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-4.0.0.tgz#f037aef1580bb3a1a35164ea2a848ba81b445983" + integrity sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g== + dependencies: + node-fetch "^2.6.12" + +cross-spawn@^7.0.1: + version "7.0.6" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" + integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +crypt@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" + integrity sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow== + +css-select@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-5.1.0.tgz#b8ebd6554c3637ccc76688804ad3f6a6fdaea8a6" + integrity sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg== + dependencies: + boolbase "^1.0.0" + css-what "^6.1.0" + domhandler "^5.0.2" + domutils "^3.0.1" + nth-check "^2.0.1" + +css-what@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" + integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== + +data-uri-to-buffer@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz#8a58bb67384b261a38ef18bea1810cb01badd28b" + integrity sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw== + +debug@2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@4, debug@4.3.4, debug@^4.1.1, debug@^4.3.4: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +debug@^3.1.0, debug@^3.2.7: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + +decamelize@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== + +decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + +decompress-tar@^4.0.0, decompress-tar@^4.1.0, decompress-tar@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/decompress-tar/-/decompress-tar-4.1.1.tgz#718cbd3fcb16209716e70a26b84e7ba4592e5af1" + integrity sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ== + dependencies: + file-type "^5.2.0" + is-stream "^1.1.0" + tar-stream "^1.5.2" + +decompress-tarbz2@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz#3082a5b880ea4043816349f378b56c516be1a39b" + integrity sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A== + dependencies: + decompress-tar "^4.1.0" + file-type "^6.1.0" + is-stream "^1.1.0" + seek-bzip "^1.0.5" + unbzip2-stream "^1.0.9" + +decompress-targz@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/decompress-targz/-/decompress-targz-4.1.1.tgz#c09bc35c4d11f3de09f2d2da53e9de23e7ce1eee" + integrity sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w== + dependencies: + decompress-tar "^4.1.1" + file-type "^5.2.0" + is-stream "^1.1.0" + +decompress-unzip@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/decompress-unzip/-/decompress-unzip-4.0.1.tgz#deaaccdfd14aeaf85578f733ae8210f9b4848f69" + integrity sha512-1fqeluvxgnn86MOh66u8FjbtJpAFv5wgCT9Iw8rcBqQcCo5tO8eiJw7NNTrvt9n4CRBVq7CstiS922oPgyGLrw== + dependencies: + file-type "^3.8.0" + get-stream "^2.2.0" + pify "^2.3.0" + yauzl "^2.4.2" + +decompress@^4.2.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/decompress/-/decompress-4.2.1.tgz#007f55cc6a62c055afa37c07eb6a4ee1b773f118" + integrity sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ== + dependencies: + decompress-tar "^4.0.0" + decompress-tarbz2 "^4.0.0" + decompress-targz "^4.0.0" + decompress-unzip "^4.0.1" + graceful-fs "^4.1.10" + make-dir "^1.0.0" + pify "^2.3.0" + strip-dirs "^2.0.0" + +"deep-eql@= 4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.0.0.tgz#c70af2713a4e18d9c2c1203ff9d11abbd51c8fbd" + integrity sha512-GxJC5MOg2KyQlv6WiUF/VAnMj4MWnYiXo4oLgeptOELVoknyErb4Z8+5F/IM/K4g9/80YzzatxmWcyRwUseH0A== + dependencies: + type-detect "^4.0.0" + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + +deepmerge@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" + integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== + +define-data-property@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" + integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + gopd "^1.0.1" + +degenerator@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/degenerator/-/degenerator-5.0.1.tgz#9403bf297c6dad9a1ece409b37db27954f91f2f5" + integrity sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ== + dependencies: + ast-types "^0.13.4" + escodegen "^2.1.0" + esprima "^4.0.1" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== + +depd@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + +destroy@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + +detect-libc@^2.0.0, detect-libc@^2.0.2, detect-libc@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.3.tgz#f0cd503b40f9939b894697d19ad50895e30cf700" + integrity sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw== + +devtools-protocol@0.0.1203626: + version "0.0.1203626" + resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.1203626.tgz#4366a4c81a7e0d4fd6924e9182c67f1e5941e820" + integrity sha512-nEzHZteIUZfGCZtTiS1fRpC8UZmsfD1SiyPvaUNvS13dvKf666OAm8YTi0+Ca3n1nLEyu49Cy4+dPWpaHFJk9g== + +digest-fetch@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/digest-fetch/-/digest-fetch-1.3.0.tgz#898e69264d00012a23cf26e8a3e40320143fc661" + integrity sha512-CGJuv6iKNM7QyZlM2T3sPAdZWd/p9zQiRNS9G+9COUCwzWFTs0Xp8NF5iePx7wtvhDykReiRRrSeNb4oMmB8lA== + dependencies: + base-64 "^0.1.0" + md5 "^2.3.0" + +dingbat-to-unicode@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/dingbat-to-unicode/-/dingbat-to-unicode-1.0.1.tgz#5091dd673241453e6b5865e26e5a4452cdef5c83" + integrity sha512-98l0sW87ZT58pU4i61wa2OHwxbiYSbuxsCBozaVnYX2iCnr3bLM3fIes1/ej7h1YdOKuKt/MLs706TVnALA65w== + +dom-serializer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53" + integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.2" + entities "^4.2.0" + +domelementtype@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" + integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== + +domhandler@^5.0.2, domhandler@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31" + integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w== + dependencies: + domelementtype "^2.3.0" + +domutils@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.1.0.tgz#c47f551278d3dc4b0b1ab8cbb42d751a6f0d824e" + integrity sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA== + dependencies: + dom-serializer "^2.0.0" + domelementtype "^2.3.0" + domhandler "^5.0.3" + +dotenv@^16.0.3: + version "16.4.5" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f" + integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg== + +duck@^0.1.12: + version "0.1.12" + resolved "https://registry.yarnpkg.com/duck/-/duck-0.1.12.tgz#de7adf758421230b6d7aee799ce42670586b9efa" + integrity sha512-wkctla1O6VfP89gQ+J/yDesM0S7B7XLXjKGzXxMDVFg7uEn706niAtyYovKbyq1oT9YwDcly721/iUWoc8MVRg== + dependencies: + underscore "^1.13.1" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +enabled@2.0.x: + version "2.0.0" + resolved "https://registry.yarnpkg.com/enabled/-/enabled-2.0.0.tgz#f9dd92ec2d6f4bbc0d5d1e64e21d61cd4665e7c2" + integrity sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== + +encoding-japanese@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/encoding-japanese/-/encoding-japanese-2.0.0.tgz#fa0226e5469e7b5b69a04fea7d5481bd1fa56936" + integrity sha512-++P0RhebUC8MJAwJOsT93dT+5oc5oPImp1HubZpAuCZ5kTLnhuuBhKHj2jJeO/Gj93idPBWmIuQ9QWMe5rX3pQ== + +encoding-japanese@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/encoding-japanese/-/encoding-japanese-2.1.0.tgz#5d3c2b652c84ca563783b86907bf5cdfe9a597e2" + integrity sha512-58XySVxUgVlBikBTbQ8WdDxBDHIdXucB16LO5PBHR8t75D54wQrNo4cg+58+R1CtJfKnsVsvt9XlteRaR8xw1w== + +end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +entities@^4.2.0, entities@^4.4.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" + integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== + +epub2@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/epub2/-/epub2-3.0.2.tgz#eee764e2b6b965d36c7713736bd49f6941d8c9c4" + integrity sha512-rhvpt27CV5MZfRetfNtdNwi3XcNg1Am0TwfveJkK8YWeHItHepQ8Js9J06v8XRIjuTrCW/NSGYMTy55Of7BfNQ== + dependencies: + adm-zip "^0.5.10" + array-hyper-unique "^2.1.4" + bluebird "^3.7.2" + crlf-normalize "^1.0.19" + tslib "^2.6.2" + xml2js "^0.6.2" + +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +es-define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845" + integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ== + dependencies: + get-intrinsic "^1.2.4" + +es-errors@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" + integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== + +escalade@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27" + integrity sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA== + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + +escodegen@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.1.0.tgz#ba93bbb7a43986d29d6041f99f5262da773e2e17" + integrity sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w== + dependencies: + esprima "^4.0.1" + estraverse "^5.2.0" + esutils "^2.0.2" + optionalDependencies: + source-map "~0.6.1" + +esprima@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== + +event-target-shim@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" + integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== + +eventemitter3@^4.0.4: + version "4.0.7" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== + +expand-template@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" + integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== + +expr-eval@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/expr-eval/-/expr-eval-2.0.2.tgz#fa6f044a7b0c93fde830954eb9c5b0f7fbc7e201" + integrity sha512-4EMSHGOPSwAfBiibw3ndnP0AvjDWLsMvGOvWEZ2F96IGk0bIVdjQisOHxReSkE13mHcfbuCiXw+G4y0zv6N8Eg== + +express@^4.18.2: + version "4.19.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.19.2.tgz#e25437827a3aa7f2a827bc8171bbbb664a356465" + integrity sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.20.2" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.6.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "2.0.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.2.0" + fresh "0.5.2" + http-errors "2.0.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "2.4.1" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.11.0" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.18.0" + serve-static "1.15.0" + setprototypeof "1.2.0" + statuses "2.0.1" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +extract-zip@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-2.0.1.tgz#663dca56fe46df890d5f131ef4a06d22bb8ba13a" + integrity sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg== + dependencies: + debug "^4.1.1" + get-stream "^5.1.0" + yauzl "^2.10.0" + optionalDependencies: + "@types/yauzl" "^2.9.1" + +fast-fifo@^1.1.0, fast-fifo@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/fast-fifo/-/fast-fifo-1.3.2.tgz#286e31de96eb96d38a97899815740ba2a4f3640c" + integrity sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ== + +fd-slicer@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" + integrity sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g== + dependencies: + pend "~1.2.0" + +fecha@^4.2.0: + version "4.2.3" + resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.3.tgz#4d9ccdbc61e8629b259fdca67e65891448d569fd" + integrity sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw== + +file-type@^16.5.4: + version "16.5.4" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-16.5.4.tgz#474fb4f704bee427681f98dd390058a172a6c2fd" + integrity sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw== + dependencies: + readable-web-to-node-stream "^3.0.0" + strtok3 "^6.2.4" + token-types "^4.1.1" + +file-type@^3.8.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9" + integrity sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA== + +file-type@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-5.2.0.tgz#2ddbea7c73ffe36368dfae49dc338c058c2b8ad6" + integrity sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ== + +file-type@^6.1.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-6.2.0.tgz#e50cd75d356ffed4e306dc4f5bcf52a79903a919" + integrity sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg== + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" + integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "2.4.1" + parseurl "~1.3.3" + statuses "2.0.1" + unpipe "~1.0.0" + +flat@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== + +flatbuffers@^1.12.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/flatbuffers/-/flatbuffers-1.12.0.tgz#72e87d1726cb1b216e839ef02658aa87dcef68aa" + integrity sha512-c7CZADjRcl6j0PlvFy0ZqXQ67qSEZfrVPynmnL+2zPc+NtMvrF8Y0QceMo7QqnSPc7+uWjUIAbvCQ5WIKlMVdQ== + +fluent-ffmpeg@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/fluent-ffmpeg/-/fluent-ffmpeg-2.1.2.tgz#c952de2240f812ebda0aa8006d7776ee2acf7d74" + integrity sha512-IZTB4kq5GK0DPp7sGQ0q/BWurGHffRtQQwVkiqDgeO6wYJLLV5ZhgNOQ65loZxxuPMKZKZcICCUnaGtlxBiR0Q== + dependencies: + async ">=0.2.9" + which "^1.1.1" + +fn.name@1.x.x: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fn.name/-/fn.name-1.1.0.tgz#26cad8017967aea8731bc42961d04a3d5988accc" + integrity sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw== + +form-data-encoder@1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/form-data-encoder/-/form-data-encoder-1.7.2.tgz#1f1ae3dccf58ed4690b86d87e4f57c654fbab040" + integrity sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A== + +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + +formdata-node@^4.3.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/formdata-node/-/formdata-node-4.4.1.tgz#23f6a5cb9cb55315912cbec4ff7b0f59bbd191e2" + integrity sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ== + dependencies: + node-domexception "1.0.0" + web-streams-polyfill "4.0.0-beta.3" + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== + +fs-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== + +fs-extra@^11.2.0: + version "11.2.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.2.0.tgz#e70e17dfad64232287d01929399e0ea7c86b0e5b" + integrity sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fs-minipass@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" + integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== + dependencies: + minipass "^3.0.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== + +gauge@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-3.0.2.tgz#03bf4441c044383908bcfa0656ad91803259b395" + integrity sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q== + dependencies: + aproba "^1.0.3 || ^2.0.0" + color-support "^1.1.2" + console-control-strings "^1.0.0" + has-unicode "^2.0.1" + object-assign "^4.1.1" + signal-exit "^3.0.0" + string-width "^4.2.3" + strip-ansi "^6.0.1" + wide-align "^1.1.2" + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-intrinsic@^1.1.3, get-intrinsic@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" + integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== + dependencies: + es-errors "^1.3.0" + function-bind "^1.1.2" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.0" + +get-stream@^2.2.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de" + integrity sha512-AUGhbbemXxrZJRD5cDvKtQxLuYaIbNtDTK8YqupCI393Q2KSTreEsLUN3ZxAWFGiKTzL6nKuzfcIvieflUX9qA== + dependencies: + object-assign "^4.0.1" + pinkie-promise "^2.0.0" + +get-stream@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== + dependencies: + pump "^3.0.0" + +get-uri@^6.0.1: + version "6.0.3" + resolved "https://registry.yarnpkg.com/get-uri/-/get-uri-6.0.3.tgz#0d26697bc13cf91092e519aa63aa60ee5b6f385a" + integrity sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw== + dependencies: + basic-ftp "^5.0.2" + data-uri-to-buffer "^6.0.2" + debug "^4.3.4" + fs-extra "^11.2.0" + +github-from-package@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" + integrity sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw== + +glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob@^7.1.3: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + 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" + +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + +graceful-fs@^4.1.10, graceful-fs@^4.1.6, graceful-fs@^4.2.0: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + +guid-typescript@^1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/guid-typescript/-/guid-typescript-1.0.9.tgz#e35f77003535b0297ea08548f5ace6adb1480ddc" + integrity sha512-Y8T4vYhEfwJOTbouREvG+3XDsjr8E3kIr7uf+JZ0BYloFsttiHU0WfvANVsR7TxNUJa/WpCnw/Ino/p+DeBhBQ== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + +has-property-descriptors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" + integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== + dependencies: + es-define-property "^1.0.0" + +has-proto@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd" + integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q== + +has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +has-unicode@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== + +hasown@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" + integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== + dependencies: + function-bind "^1.1.2" + +he@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +html-to-text@9.0.5, html-to-text@^9.0.5: + version "9.0.5" + resolved "https://registry.yarnpkg.com/html-to-text/-/html-to-text-9.0.5.tgz#6149a0f618ae7a0db8085dca9bbf96d32bb8368d" + integrity sha512-qY60FjREgVZL03vJU6IfMV4GDjGBIoOyvuFdpBDIX9yTlDw0TjxVBQp+P8NvpdIXNJvfWBTNul7fsAQJq2FNpg== + dependencies: + "@selderee/plugin-htmlparser2" "^0.11.0" + deepmerge "^4.3.1" + dom-serializer "^2.0.0" + htmlparser2 "^8.0.2" + selderee "^0.11.0" + +htmlparser2@^8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-8.0.2.tgz#f002151705b383e62433b5cf466f5b716edaec21" + integrity sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.3" + domutils "^3.0.1" + entities "^4.4.0" + +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + +http-proxy-agent@^7.0.0: + version "7.0.2" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz#9a8b1f246866c028509486585f62b8f2c18c270e" + integrity sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig== + dependencies: + agent-base "^7.1.0" + debug "^4.3.4" + +https-proxy-agent@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" + integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== + dependencies: + agent-base "6" + debug "4" + +https-proxy-agent@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz#8e97b841a029ad8ddc8731f26595bad868cb4168" + integrity sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg== + dependencies: + agent-base "^7.0.2" + debug "4" + +humanize-duration@^3.25.1: + version "3.32.0" + resolved "https://registry.yarnpkg.com/humanize-duration/-/humanize-duration-3.32.0.tgz#b25f64ef55d723b049b197b6b4aa3c96c202b6c9" + integrity sha512-6WsXYTHJr7hXKqoqf5zoWza/lANRAqGlbnZnm0cjDykbXuez1JVXOQGmq0EPB45pXYAJyueRA3S3hfhmMbrMEQ== + +humanize-ms@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" + integrity sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ== + dependencies: + ms "^2.0.0" + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +iconv-lite@0.6.3, iconv-lite@^0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + +idb-keyval@^6.2.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/idb-keyval/-/idb-keyval-6.2.1.tgz#94516d625346d16f56f3b33855da11bfded2db33" + integrity sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg== + +ieee754@^1.1.13, ieee754@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + +ignore-by-default@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" + integrity sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA== + +ignore@^5.3.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.1.tgz#5073e554cd42c5b33b394375f538b8593e34d4ef" + integrity sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw== + +immediate@~3.0.5: + version "3.0.6" + resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" + integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ== + +import-fresh@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +ini@~1.3.0: + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + +ip-address@^9.0.5: + version "9.0.5" + resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-9.0.5.tgz#117a960819b08780c3bd1f14ef3c1cc1d3f3ea5a" + integrity sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g== + dependencies: + jsbn "1.1.0" + sprintf-js "^1.1.3" + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +is-any-array@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-any-array/-/is-any-array-2.0.1.tgz#9233242a9c098220290aa2ec28f82ca7fa79899e" + integrity sha512-UtilS7hLRu++wb/WBAw9bNuP1Eg04Ivn1vERJck8zJthEvXCBEBpGR/33u/xLKWEQf95803oalHrVDptcAvFdQ== + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== + +is-arrayish@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" + integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-buffer@~1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-natural-number@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-natural-number/-/is-natural-number-4.0.1.tgz#ab9d76e1db4ced51e35de0c72ebecf09f734cde8" + integrity sha512-Y4LTamMe0DDQIIAlaer9eKebAlDSV6huy+TWhJVPlzZh2o4tRP5SQWFlLn5N0To4mDD22/qdOq+veo1cSISLgQ== + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ== + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +is-url@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.4.tgz#04a4df46d28c4cff3d73d01ff06abeb318a1aa52" + integrity sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww== + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +jintr@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/jintr/-/jintr-1.1.0.tgz#223a3b07f5e03d410cec6e715c537c8ad1e714c3" + integrity sha512-Tu9wk3BpN2v+kb8yT6YBtue+/nbjeLFv4vvVC4PJ7oCidHKbifWhvORrAbQfxVIQZG+67am/mDagpiGSVtvrZg== + dependencies: + acorn "^8.8.0" + +js-tiktoken@^1.0.11, js-tiktoken@^1.0.7, js-tiktoken@^1.0.8: + version "1.0.11" + resolved "https://registry.yarnpkg.com/js-tiktoken/-/js-tiktoken-1.0.11.tgz#d7d707b849f703841112660d9d55169424a35344" + integrity sha512-PajXFLq2vx7/8jllQZ43vzNpAai/0MOVdJjW/UrNyJorNQRTjHrqdGJG/mjHVy7h9M6dW6CaG43eNLMYFkTh6w== + dependencies: + base64-js "^1.5.1" + +js-tiktoken@^1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/js-tiktoken/-/js-tiktoken-1.0.12.tgz#af0f5cf58e5e7318240d050c8413234019424211" + integrity sha512-L7wURW1fH9Qaext0VzaUDpFGVQgjkdE3Dgsy9/+yXyGEpBKnylTd0mU0bfbNkKDlXRb6TEsZkwuflu1B8uQbJQ== + dependencies: + base64-js "^1.5.1" + +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +jsbn@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-1.1.0.tgz#b01307cb29b618a1ed26ec79e911f803c4da0040" + integrity sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A== + +json-parse-even-better-errors@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + +jsonpointer@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-5.0.1.tgz#2110e0af0900fd37467b5907ecd13a7884a1b559" + integrity sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ== + +jszip@^3.7.1: + version "3.10.1" + resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.10.1.tgz#34aee70eb18ea1faec2f589208a157d1feb091c2" + integrity sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g== + dependencies: + lie "~3.3.0" + pako "~1.0.2" + readable-stream "~2.3.6" + setimmediate "^1.0.5" + +kuler@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/kuler/-/kuler-2.0.0.tgz#e2c570a3800388fb44407e851531c1d670b061b3" + integrity sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A== + +langchain@0.1.36: + version "0.1.36" + resolved "https://registry.yarnpkg.com/langchain/-/langchain-0.1.36.tgz#2f201f681d83fb265716e28e7dfcfe61fbeef2c2" + integrity sha512-NTbnCL/jKWIeEI//Nm1oG8nhW3vkYWvEMr1MPotmTThTfeKfO87eV/OAzAyh6Ruy6GFs/qofRgQZGIe6XvXTNQ== + dependencies: + "@anthropic-ai/sdk" "^0.9.1" + "@langchain/community" "~0.0.47" + "@langchain/core" "~0.1.60" + "@langchain/openai" "~0.0.28" + "@langchain/textsplitters" "~0.0.0" + binary-extensions "^2.2.0" + js-tiktoken "^1.0.7" + js-yaml "^4.1.0" + jsonpointer "^5.0.1" + langchainhub "~0.0.8" + langsmith "~0.1.7" + ml-distance "^4.0.0" + openapi-types "^12.1.3" + p-retry "4" + uuid "^9.0.0" + yaml "^2.2.1" + zod "^3.22.4" + zod-to-json-schema "^3.22.3" + +langchain@~0.2.3: + version "0.2.12" + resolved "https://registry.yarnpkg.com/langchain/-/langchain-0.2.12.tgz#3fac0b9519a070689b6dd679d5854abc57824dcf" + integrity sha512-ZHtJrHUpridZ7IQu7N/wAQ6iMAAO7VLzkupHqKP79S6p+alrPbn1BjRnh+PeGm92YiY5DafTCuvchmujxx7bCQ== + dependencies: + "@langchain/core" ">=0.2.11 <0.3.0" + "@langchain/openai" ">=0.1.0 <0.3.0" + "@langchain/textsplitters" "~0.0.0" + binary-extensions "^2.2.0" + js-tiktoken "^1.0.12" + js-yaml "^4.1.0" + jsonpointer "^5.0.1" + langchainhub "~0.0.8" + langsmith "~0.1.30" + ml-distance "^4.0.0" + openapi-types "^12.1.3" + p-retry "4" + uuid "^10.0.0" + yaml "^2.2.1" + zod "^3.22.4" + zod-to-json-schema "^3.22.3" + +langchainhub@~0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/langchainhub/-/langchainhub-0.0.8.tgz#fd4b96dc795e22e36c1a20bad31b61b0c33d3110" + integrity sha512-Woyb8YDHgqqTOZvWIbm2CaFDGfZ4NTSyXV687AG4vXEfoNo7cGQp7nhl7wL3ehenKWmNEmcxCLgOZzW8jE6lOQ== + +langsmith@~0.1.1, langsmith@~0.1.7: + version "0.1.21" + resolved "https://registry.yarnpkg.com/langsmith/-/langsmith-0.1.21.tgz#0e6cb361b4dddcc713f9d1364509fea0da3429b6" + integrity sha512-pC9uujQAQFez9IdkPK4LPJLTnHLRKElImcYGxDrOJTZ2KZ/LIsRn6kPLKx1ZdT9h5CbDbT+ivXiS4bsxQGcbXA== + dependencies: + "@types/uuid" "^9.0.1" + commander "^10.0.1" + p-queue "^6.6.2" + p-retry "4" + uuid "^9.0.0" + +langsmith@~0.1.30, langsmith@~0.1.39: + version "0.1.40" + resolved "https://registry.yarnpkg.com/langsmith/-/langsmith-0.1.40.tgz#9708889386a5b9d0eb43dd3a9eba93513b57101d" + integrity sha512-11E2WLbh/+41+Qc0w8fJJTC/iz91BA+zXRMX/Wz0KSstnfzIPBoiWa++Kp2X8yCIDNywWWLJhy/B8gYzm7VKig== + dependencies: + "@types/uuid" "^9.0.1" + commander "^10.0.1" + p-queue "^6.6.2" + p-retry "4" + semver "^7.6.3" + uuid "^9.0.0" + +leac@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/leac/-/leac-0.6.0.tgz#dcf136e382e666bd2475f44a1096061b70dc0912" + integrity sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg== + +libbase64@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/libbase64/-/libbase64-1.2.1.tgz#fb93bf4cb6d730f29b92155b6408d1bd2176a8c8" + integrity sha512-l+nePcPbIG1fNlqMzrh68MLkX/gTxk/+vdvAb388Ssi7UuUN31MI44w4Yf33mM3Cm4xDfw48mdf3rkdHszLNew== + +libbase64@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/libbase64/-/libbase64-1.3.0.tgz#053314755a05d2e5f08bbfc48d0290e9322f4406" + integrity sha512-GgOXd0Eo6phYgh0DJtjQ2tO8dc0IVINtZJeARPeiIJqge+HdsWSuaDTe8ztQ7j/cONByDZ3zeB325AHiv5O0dg== + +libmime@5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/libmime/-/libmime-5.2.0.tgz#c4ed5cbd2d9fdd27534543a68bb8d17c658d51d8" + integrity sha512-X2U5Wx0YmK0rXFbk67ASMeqYIkZ6E5vY7pNWRKtnNzqjvdYYG8xtPDpCnuUEnPU9vlgNev+JoSrcaKSUaNvfsw== + dependencies: + encoding-japanese "2.0.0" + iconv-lite "0.6.3" + libbase64 "1.2.1" + libqp "2.0.1" + +libmime@5.3.5: + version "5.3.5" + resolved "https://registry.yarnpkg.com/libmime/-/libmime-5.3.5.tgz#acd95a32f58dab55c8a9d269c5b4509e7ad6ae31" + integrity sha512-nSlR1yRZ43L3cZCiWEw7ali3jY29Hz9CQQ96Oy+sSspYnIP5N54ucOPHqooBsXzwrX1pwn13VUE05q4WmzfaLg== + dependencies: + encoding-japanese "2.1.0" + iconv-lite "0.6.3" + libbase64 "1.3.0" + libqp "2.1.0" + +libqp@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/libqp/-/libqp-2.0.1.tgz#b8fed76cc1ea6c9ceff8888169e4e0de70cd5cf2" + integrity sha512-Ka0eC5LkF3IPNQHJmYBWljJsw0UvM6j+QdKRbWyCdTmYwvIDE6a7bCm0UkTAL/K+3KXK5qXT/ClcInU01OpdLg== + +libqp@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/libqp/-/libqp-2.1.0.tgz#ce84bffd86b76029032093bd866d316e12a3d3f5" + integrity sha512-O6O6/fsG5jiUVbvdgT7YX3xY3uIadR6wEZ7+vy9u7PKHAlSEB6blvC1o5pHBjgsi95Uo0aiBBdkyFecj6jtb7A== + +lie@~3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/lie/-/lie-3.3.0.tgz#dcf82dee545f46074daf200c7c1c5a08e0f40f6a" + integrity sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ== + dependencies: + immediate "~3.0.5" + +lines-and-columns@^1.1.6: + version "1.2.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== + +linkify-it@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-5.0.0.tgz#9ef238bfa6dc70bd8e7f9572b52d369af569b421" + integrity sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ== + dependencies: + uc.micro "^2.0.0" + +lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +logform@^2.3.2, logform@^2.4.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/logform/-/logform-2.6.0.tgz#8c82a983f05d6eaeb2d75e3decae7a768b2bf9b5" + integrity sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ== + dependencies: + "@colors/colors" "1.6.0" + "@types/triple-beam" "^1.3.2" + fecha "^4.2.0" + ms "^2.1.1" + safe-stable-stringify "^2.3.1" + triple-beam "^1.3.0" + +long@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" + integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== + +lop@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/lop/-/lop-0.4.1.tgz#744f1696ef480e68ce1947fe557b09db5af2a738" + integrity sha512-9xyho9why2A2tzm5aIcMWKvzqKsnxrf9B5I+8O30olh6lQU8PH978LqZoI4++37RBgS1Em5i54v1TFs/3wnmXQ== + dependencies: + duck "^0.1.12" + option "~0.2.1" + underscore "^1.13.1" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +lru-cache@^7.14.1: + version "7.18.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89" + integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== + +mailparser@^3.0.1: + version "3.7.1" + resolved "https://registry.yarnpkg.com/mailparser/-/mailparser-3.7.1.tgz#4d0ea2eeb50a73dd10854a71ef1d4553bdce01cb" + integrity sha512-RCnBhy5q8XtB3mXzxcAfT1huNqN93HTYYyL6XawlIKycfxM/rXPg9tXoZ7D46+SgCS1zxKzw+BayDQSvncSTTw== + dependencies: + encoding-japanese "2.1.0" + he "1.2.0" + html-to-text "9.0.5" + iconv-lite "0.6.3" + libmime "5.3.5" + linkify-it "5.0.0" + mailsplit "5.4.0" + nodemailer "6.9.13" + punycode.js "2.3.1" + tlds "1.252.0" + +mailsplit@5.4.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/mailsplit/-/mailsplit-5.4.0.tgz#9f4692fadd9013e9ce632147d996931d2abac6ba" + integrity sha512-wnYxX5D5qymGIPYLwnp6h8n1+6P6vz/MJn5AzGjZ8pwICWssL+CCQjWBIToOVHASmATot4ktvlLo6CyLfOXWYA== + dependencies: + libbase64 "1.2.1" + libmime "5.2.0" + libqp "2.0.1" + +make-dir@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" + integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== + dependencies: + pify "^3.0.0" + +make-dir@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + +mammoth@^1.6.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/mammoth/-/mammoth-1.8.0.tgz#d8f1b0d3a0355fda129270346e9dc853f223028f" + integrity sha512-pJNfxSk9IEGVpau+tsZFz22ofjUsl2mnA5eT8PjPs2n0BP+rhVte4Nez6FdgEuxv3IGI3afiV46ImKqTGDVlbA== + dependencies: + "@xmldom/xmldom" "^0.8.6" + argparse "~1.0.3" + base64-js "^1.5.1" + bluebird "~3.4.0" + dingbat-to-unicode "^1.0.1" + jszip "^3.7.1" + lop "^0.4.1" + path-is-absolute "^1.0.0" + underscore "^1.13.1" + xmlbuilder "^10.0.0" + +mbox-parser@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mbox-parser/-/mbox-parser-1.0.1.tgz#cba6bb372a1d3c27aff9da356b4519aeee458e1f" + integrity sha512-9PNE026G/SodrYYxZiDZDJ5YQ0piN8QCqO662MupIGwgsvBtJHFPxYc/uUsQyhUysl4kMG0NLYvfELNkM5+HzQ== + dependencies: + "@types/mailparser" "^3.0.0" + humanize-duration "^3.25.1" + mailparser "^3.0.1" + +md5@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/md5/-/md5-2.3.0.tgz#c3da9a6aae3a30b46b7b0c349b87b110dc3bda4f" + integrity sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g== + dependencies: + charenc "0.0.2" + crypt "0.0.2" + is-buffer "~1.1.6" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== + +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.12, mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mime@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-3.0.0.tgz#b374550dca3a0c18443b0c950a6a58f1931cf7a7" + integrity sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A== + +mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== + +minimatch@^3.1.1, minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.2.0, minimist@^1.2.3: + version "1.2.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + +minipass@^3.0.0: + version "3.3.6" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a" + integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== + dependencies: + yallist "^4.0.0" + +minipass@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d" + integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== + +minizlib@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" + integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== + dependencies: + minipass "^3.0.0" + yallist "^4.0.0" + +mitt@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/mitt/-/mitt-3.0.1.tgz#ea36cf0cc30403601ae074c8f77b7092cdab36d1" + integrity sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw== + +mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" + integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== + +mkdirp@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + +ml-array-mean@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/ml-array-mean/-/ml-array-mean-1.1.6.tgz#d951a700dc8e3a17b3e0a583c2c64abd0c619c56" + integrity sha512-MIdf7Zc8HznwIisyiJGRH9tRigg3Yf4FldW8DxKxpCCv/g5CafTw0RRu51nojVEOXuCQC7DRVVu5c7XXO/5joQ== + dependencies: + ml-array-sum "^1.1.6" + +ml-array-sum@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/ml-array-sum/-/ml-array-sum-1.1.6.tgz#d1d89c20793cd29c37b09d40e85681aa4515a955" + integrity sha512-29mAh2GwH7ZmiRnup4UyibQZB9+ZLyMShvt4cH4eTK+cL2oEMIZFnSyB3SS8MlsTh6q/w/yh48KmqLxmovN4Dw== + dependencies: + is-any-array "^2.0.0" + +ml-distance-euclidean@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ml-distance-euclidean/-/ml-distance-euclidean-2.0.0.tgz#3a668d236649d1b8fec96380b9435c6f42c9a817" + integrity sha512-yC9/2o8QF0A3m/0IXqCTXCzz2pNEzvmcE/9HFKOZGnTjatvBbsn4lWYJkxENkA4Ug2fnYl7PXQxnPi21sgMy/Q== + +ml-distance@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/ml-distance/-/ml-distance-4.0.1.tgz#4741d17a1735888c5388823762271dfe604bd019" + integrity sha512-feZ5ziXs01zhyFUUUeZV5hwc0f5JW0Sh0ckU1koZe/wdVkJdGxcP06KNQuF0WBTj8FttQUzcvQcpcrOp/XrlEw== + dependencies: + ml-array-mean "^1.1.6" + ml-distance-euclidean "^2.0.0" + ml-tree-similarity "^1.0.0" + +ml-tree-similarity@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ml-tree-similarity/-/ml-tree-similarity-1.0.0.tgz#24705a107e32829e24d945e87219e892159c53f0" + integrity sha512-XJUyYqjSuUQkNQHMscr6tcjldsOoAekxADTplt40QKfwW6nd++1wHWV9AArl0Zvw/TIHgNaZZNvr8QGvE8wLRg== + dependencies: + binary-search "^1.3.5" + num-sort "^2.0.0" + +moment@^2.29.4: + version "2.30.1" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.30.1.tgz#f8c91c07b7a786e30c59926df530b4eac96974ae" + integrity sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how== + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@2.1.3, ms@^2.0.0, ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +mustache@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/mustache/-/mustache-4.2.0.tgz#e5892324d60a12ec9c2a73359edca52972bf6f64" + integrity sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ== + +napi-build-utils@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806" + integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== + +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + +netmask@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/netmask/-/netmask-2.0.2.tgz#8b01a07644065d536383835823bc52004ebac5e7" + integrity sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg== + +node-abi@^3.3.0: + version "3.62.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.62.0.tgz#017958ed120f89a3a14a7253da810f5d724e3f36" + integrity sha512-CPMcGa+y33xuL1E0TcNIu4YyaZCxnnvkVaEXrsosR3FxN+fV8xvb7Mzpb7IgKler10qeMkE6+Dp8qJhpzdq35g== + dependencies: + semver "^7.3.5" + +node-addon-api@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-5.1.0.tgz#49da1ca055e109a23d537e9de43c09cca21eb762" + integrity sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA== + +node-addon-api@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-6.1.0.tgz#ac8470034e58e67d0c6f1204a18ae6995d9c0d76" + integrity sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA== + +node-domexception@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5" + integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ== + +node-ensure@^0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/node-ensure/-/node-ensure-0.0.0.tgz#ecae764150de99861ec5c810fd5d096b183932a7" + integrity sha512-DRI60hzo2oKN1ma0ckc6nQWlHU69RH6xN0sjQTjMpChPfTYvKZdcQFfdYK2RWbJcKyUizSIy/l8OTGxMAM1QDw== + +node-fetch@^2.6.12, node-fetch@^2.6.7, node-fetch@^2.6.9: + version "2.7.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" + integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== + dependencies: + whatwg-url "^5.0.0" + +node-html-parser@^6.1.13: + version "6.1.13" + resolved "https://registry.yarnpkg.com/node-html-parser/-/node-html-parser-6.1.13.tgz#a1df799b83df5c6743fcd92740ba14682083b7e4" + integrity sha512-qIsTMOY4C/dAa5Q5vsobRpOOvPfC4pB61UVW2uSwZNUp0QU/jCekTal1vMmbO0DgdHeLUJpv/ARmDqErVxA3Sg== + dependencies: + css-select "^5.1.0" + he "1.2.0" + +node-xlsx@^0.24.0: + version "0.24.0" + resolved "https://registry.yarnpkg.com/node-xlsx/-/node-xlsx-0.24.0.tgz#a6a365acb18ad37c66c2b254b6ebe0c22dc9dc6f" + integrity sha512-1olwK48XK9nXZsyH/FCltvGrQYvXXZuxVitxXXv2GIuRm51aBi1+5KwR4rWM4KeO61sFU+00913WLZTD+AcXEg== + dependencies: + xlsx "https://cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz" + +nodemailer@6.9.13: + version "6.9.13" + resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.9.13.tgz#5b292bf1e92645f4852ca872c56a6ba6c4a3d3d6" + integrity sha512-7o38Yogx6krdoBf3jCAqnIN4oSQFx+fMa0I7dK1D+me9kBxx12D+/33wSb+fhOCtIxvYJ+4x4IMEhmhCKfAiOA== + +nodemon@^2.0.22: + version "2.0.22" + resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.22.tgz#182c45c3a78da486f673d6c1702e00728daf5258" + integrity sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ== + dependencies: + chokidar "^3.5.2" + debug "^3.2.7" + ignore-by-default "^1.0.1" + minimatch "^3.1.2" + pstree.remy "^1.1.8" + semver "^5.7.1" + simple-update-notifier "^1.0.7" + supports-color "^5.5.0" + touch "^3.1.0" + undefsafe "^2.0.5" + +nopt@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" + integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== + dependencies: + abbrev "1" + +nopt@~1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" + integrity sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg== + dependencies: + abbrev "1" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +npmlog@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-5.0.1.tgz#f06678e80e29419ad67ab964e0fa69959c1eb8b0" + integrity sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw== + dependencies: + are-we-there-yet "^2.0.0" + console-control-strings "^1.1.0" + gauge "^3.0.0" + set-blocking "^2.0.0" + +nth-check@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" + integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== + dependencies: + boolbase "^1.0.0" + +num-sort@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/num-sort/-/num-sort-2.1.0.tgz#1cbb37aed071329fdf41151258bc011898577a9b" + integrity sha512-1MQz1Ed8z2yckoBeSfkQHHO9K1yDRxxtotKSJ9yvcTUUxSvfvzEq5GwBrjjHEpMlq/k5gvXdmJ1SbYxWtpNoVg== + +object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + +object-inspect@^1.13.1: + version "1.13.1" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" + integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== + +officeparser@^4.0.5: + version "4.0.8" + resolved "https://registry.yarnpkg.com/officeparser/-/officeparser-4.0.8.tgz#46def4a4664e8e2a36717bc5ae2bd99298eab565" + integrity sha512-dIVwWkKWwFy7qQO+8foRTTDJybs3CEJORDulCQPqirqhtiK2cETojmuekRtBcVebpcAKCXTg4dYs0mjmifwJKA== + dependencies: + "@xmldom/xmldom" "^0.8.10" + decompress "^4.2.0" + file-type "^16.5.4" + pdf-parse "^1.1.1" + rimraf "^2.6.3" + +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +one-time@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/one-time/-/one-time-1.0.0.tgz#e06bc174aed214ed58edede573b433bbf827cb45" + integrity sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g== + dependencies: + fn.name "1.x.x" + +onnx-proto@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/onnx-proto/-/onnx-proto-4.0.4.tgz#2431a25bee25148e915906dda0687aafe3b9e044" + integrity sha512-aldMOB3HRoo6q/phyB6QRQxSt895HNNw82BNyZ2CMh4bjeKv7g/c+VpAFtJuEMVfYLMbRx61hbuqnKceLeDcDA== + dependencies: + protobufjs "^6.8.8" + +onnxruntime-common@~1.14.0: + version "1.14.0" + resolved "https://registry.yarnpkg.com/onnxruntime-common/-/onnxruntime-common-1.14.0.tgz#2bb5dac5261269779aa5fb6536ca379657de8bf6" + integrity sha512-3LJpegM2iMNRX2wUmtYfeX/ytfOzNwAWKSq1HbRrKc9+uqG/FsEA0bbKZl1btQeZaXhC26l44NWpNUeXPII7Ew== + +onnxruntime-node@1.14.0: + version "1.14.0" + resolved "https://registry.yarnpkg.com/onnxruntime-node/-/onnxruntime-node-1.14.0.tgz#c4ae6c355cfae7d83abaf36dd39a905c4a010217" + integrity sha512-5ba7TWomIV/9b6NH/1x/8QEeowsb+jBEvFzU6z0T4mNsFwdPqXeFUM7uxC6QeSRkEbWu3qEB0VMjrvzN/0S9+w== + dependencies: + onnxruntime-common "~1.14.0" + +onnxruntime-web@1.14.0: + version "1.14.0" + resolved "https://registry.yarnpkg.com/onnxruntime-web/-/onnxruntime-web-1.14.0.tgz#c8cee538781b1d4c1c6b043934f4a3e6ddf1466e" + integrity sha512-Kcqf43UMfW8mCydVGcX9OMXI2VN17c0p6XvR7IPSZzBf/6lteBzXHvcEVWDPmCKuGombl997HgLqj91F11DzXw== + dependencies: + flatbuffers "^1.12.0" + guid-typescript "^1.0.9" + long "^4.0.0" + onnx-proto "^4.0.4" + onnxruntime-common "~1.14.0" + platform "^1.3.6" + +openai@4.95.1: + version "4.95.1" + resolved "https://registry.yarnpkg.com/openai/-/openai-4.95.1.tgz#7157697c2b150a546b13eb860180c4a6058051da" + integrity sha512-IqJy+ymeW+k/Wq+2YVN3693OQMMcODRtHEYOlz263MdUwnN/Dwdl9c2EXSxLLtGEHkSHAfvzpDMHI5MaWJKXjQ== + dependencies: + "@types/node" "^18.11.18" + "@types/node-fetch" "^2.6.4" + abort-controller "^3.0.0" + agentkeepalive "^4.2.1" + form-data-encoder "1.7.2" + formdata-node "^4.3.2" + node-fetch "^2.6.7" + +openai@^4.32.1: + version "4.39.1" + resolved "https://registry.yarnpkg.com/openai/-/openai-4.39.1.tgz#619687717e42094927a1977362dd03261a4c4ff3" + integrity sha512-Qe3HXHrCMjwAHXWPywUwzI4PHf9r14uyiRRuMmiJjsfv1tREYMHtgIHXNlb54ZxtYJaIj19RHYMq6UQ2hgrIJQ== + dependencies: + "@types/node" "^18.11.18" + "@types/node-fetch" "^2.6.4" + abort-controller "^3.0.0" + agentkeepalive "^4.2.1" + form-data-encoder "1.7.2" + formdata-node "^4.3.2" + node-fetch "^2.6.7" + web-streams-polyfill "^3.2.1" + +openai@^4.49.1: + version "4.54.0" + resolved "https://registry.yarnpkg.com/openai/-/openai-4.54.0.tgz#eeb209c6892b997e524181b6ddb7e27bf4d09389" + integrity sha512-e/12BdtTtj+tXs7iHm+Dm7H7WjEWnw7O52B2wSfCQ6lD5F6cvjzo7cANXy5TJ1Q3/qc8YRPT5wBTTFtP5sBp1g== + dependencies: + "@types/node" "^18.11.18" + "@types/node-fetch" "^2.6.4" + abort-controller "^3.0.0" + agentkeepalive "^4.2.1" + form-data-encoder "1.7.2" + formdata-node "^4.3.2" + node-fetch "^2.6.7" + +openapi-types@^12.1.3: + version "12.1.3" + resolved "https://registry.yarnpkg.com/openapi-types/-/openapi-types-12.1.3.tgz#471995eb26c4b97b7bd356aacf7b91b73e777dd3" + integrity sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw== + +opencollective-postinstall@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz#7a0fff978f6dbfa4d006238fbac98ed4198c3259" + integrity sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q== + +option@~0.2.1: + version "0.2.4" + resolved "https://registry.yarnpkg.com/option/-/option-0.2.4.tgz#fd475cdf98dcabb3cb397a3ba5284feb45edbfe4" + integrity sha512-pkEqbDyl8ou5cpq+VsnQbe/WlEy5qS7xPzMS1U55OCG9KPvwFD46zDbxQIj3egJSFc3D+XhYOPUzz49zQAVy7A== + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow== + +p-queue@^6.6.2: + version "6.6.2" + resolved "https://registry.yarnpkg.com/p-queue/-/p-queue-6.6.2.tgz#2068a9dcf8e67dd0ec3e7a2bcb76810faa85e426" + integrity sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ== + dependencies: + eventemitter3 "^4.0.4" + p-timeout "^3.2.0" + +p-retry@4: + version "4.6.2" + resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.2.tgz#9baae7184057edd4e17231cee04264106e092a16" + integrity sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ== + dependencies: + "@types/retry" "0.12.0" + retry "^0.13.1" + +p-timeout@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-3.2.0.tgz#c7e17abc971d2a7962ef83626b35d635acf23dfe" + integrity sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg== + dependencies: + p-finally "^1.0.0" + +pac-proxy-agent@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/pac-proxy-agent/-/pac-proxy-agent-7.0.1.tgz#6b9ddc002ec3ff0ba5fdf4a8a21d363bcc612d75" + integrity sha512-ASV8yU4LLKBAjqIPMbrgtaKIvxQri/yh2OpI+S6hVa9JRkUI3Y3NPFbfngDtY7oFtSMD3w31Xns89mDa3Feo5A== + dependencies: + "@tootallnate/quickjs-emscripten" "^0.23.0" + agent-base "^7.0.2" + debug "^4.3.4" + get-uri "^6.0.1" + http-proxy-agent "^7.0.0" + https-proxy-agent "^7.0.2" + pac-resolver "^7.0.0" + socks-proxy-agent "^8.0.2" + +pac-resolver@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/pac-resolver/-/pac-resolver-7.0.1.tgz#54675558ea368b64d210fd9c92a640b5f3b8abb6" + integrity sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg== + dependencies: + degenerator "^5.0.0" + netmask "^2.0.2" + +pako@~1.0.2: + version "1.0.11" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" + integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +parse-json@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + +parseley@^0.12.0: + version "0.12.1" + resolved "https://registry.yarnpkg.com/parseley/-/parseley-0.12.1.tgz#4afd561d50215ebe259e3e7a853e62f600683aef" + integrity sha512-e6qHKe3a9HWr0oMRVDTRhKce+bRO8VGQR3NyVwcjwrbhMmFCX9KszEV35+rn4AdilFAq9VPxP/Fe1wC9Qjd2lw== + dependencies: + leac "^0.6.0" + peberminta "^0.9.0" + +parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +pdf-parse@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/pdf-parse/-/pdf-parse-1.1.1.tgz#745e07408679548b3995ff896fd38e96e19d14a7" + integrity sha512-v6ZJ/efsBpGrGGknjtq9J/oC8tZWq0KWL5vQrk2GlzLEQPUDB1ex+13Rmidl1neNN358Jn9EHZw5y07FFtaC7A== + dependencies: + debug "^3.1.0" + node-ensure "^0.0.0" + +peberminta@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/peberminta/-/peberminta-0.9.0.tgz#8ec9bc0eb84b7d368126e71ce9033501dca2a352" + integrity sha512-XIxfHpEuSJbITd1H3EeQwpcZbTLHc+VVr8ANI9t5sit565tsI4/xK3KWTUFE2e6QiangUkh3B0jihzmGnNrRsQ== + +peek-readable@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-4.1.0.tgz#4ece1111bf5c2ad8867c314c81356847e8a62e72" + integrity sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg== + +pend@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg== + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.0.4, picomatch@^2.2.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pify@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg== + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw== + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg== + +platform@^1.3.6: + version "1.3.6" + resolved "https://registry.yarnpkg.com/platform/-/platform-1.3.6.tgz#48b4ce983164b209c2d45a107adb31f473a6e7a7" + integrity sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg== + +prebuild-install@^7.1.1: + version "7.1.2" + resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.2.tgz#a5fd9986f5a6251fbc47e1e5c65de71e68c0a056" + integrity sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ== + dependencies: + detect-libc "^2.0.0" + expand-template "^2.0.3" + github-from-package "0.0.0" + minimist "^1.2.3" + mkdirp-classic "^0.5.3" + napi-build-utils "^1.0.1" + node-abi "^3.3.0" + pump "^3.0.0" + rc "^1.2.7" + simple-get "^4.0.0" + tar-fs "^2.0.0" + tunnel-agent "^0.6.0" + +prettier@^2.4.1: + version "2.8.8" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" + integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +progress@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + +protobufjs@^6.8.8: + version "6.11.4" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.11.4.tgz#29a412c38bf70d89e537b6d02d904a6f448173aa" + integrity sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw== + dependencies: + "@protobufjs/aspromise" "^1.1.2" + "@protobufjs/base64" "^1.1.2" + "@protobufjs/codegen" "^2.0.4" + "@protobufjs/eventemitter" "^1.1.0" + "@protobufjs/fetch" "^1.1.0" + "@protobufjs/float" "^1.0.2" + "@protobufjs/inquire" "^1.1.0" + "@protobufjs/path" "^1.1.2" + "@protobufjs/pool" "^1.1.0" + "@protobufjs/utf8" "^1.1.0" + "@types/long" "^4.0.1" + "@types/node" ">=13.7.0" + long "^4.0.0" + +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +proxy-agent@6.3.1: + version "6.3.1" + resolved "https://registry.yarnpkg.com/proxy-agent/-/proxy-agent-6.3.1.tgz#40e7b230552cf44fd23ffaf7c59024b692612687" + integrity sha512-Rb5RVBy1iyqOtNl15Cw/llpeLH8bsb37gM1FUfKQ+Wck6xHlbAhWGUFiTRHtkjqGTA5pSHz6+0hrPW/oECihPQ== + dependencies: + agent-base "^7.0.2" + debug "^4.3.4" + http-proxy-agent "^7.0.0" + https-proxy-agent "^7.0.2" + lru-cache "^7.14.1" + pac-proxy-agent "^7.0.1" + proxy-from-env "^1.1.0" + socks-proxy-agent "^8.0.2" + +proxy-from-env@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + +pstree.remy@^1.1.8: + version "1.1.8" + resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a" + integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w== + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +punycode.js@2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/punycode.js/-/punycode.js-2.3.1.tgz#6b53e56ad75588234e79f4affa90972c7dd8cdb7" + integrity sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA== + +puppeteer-core@21.5.2: + version "21.5.2" + resolved "https://registry.yarnpkg.com/puppeteer-core/-/puppeteer-core-21.5.2.tgz#6d3de4efb2ae65f1ee072043787b75594e88035f" + integrity sha512-v4T0cWnujSKs+iEfmb8ccd7u4/x8oblEyKqplqKnJ582Kw8PewYAWvkH4qUWhitN3O2q9RF7dzkvjyK5HbzjLA== + dependencies: + "@puppeteer/browsers" "1.8.0" + chromium-bidi "0.4.33" + cross-fetch "4.0.0" + debug "4.3.4" + devtools-protocol "0.0.1203626" + ws "8.14.2" + +puppeteer@~21.5.2: + version "21.5.2" + resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-21.5.2.tgz#0a4a72175c0fd0944d6486f4734807e1671d527b" + integrity sha512-BaAGJOq8Fl6/cck6obmwaNLksuY0Bg/lIahCLhJPGXBFUD2mCffypa4A592MaWnDcye7eaHmSK9yot0pxctY8A== + dependencies: + "@puppeteer/browsers" "1.8.0" + cosmiconfig "8.3.6" + puppeteer-core "21.5.2" + +qs@6.11.0: + version "6.11.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" + integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== + dependencies: + side-channel "^1.0.4" + +queue-tick@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/queue-tick/-/queue-tick-1.0.1.tgz#f6f07ac82c1fd60f82e098b417a80e52f1f4c142" + integrity sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag== + +range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.5.2: + version "2.5.2" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" + integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + +rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +readable-stream@^2.3.0, readable-stream@^2.3.5, readable-stream@~2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" + integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readable-web-to-node-stream@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz#5d52bb5df7b54861fd48d015e93a2cb87b3ee0bb" + integrity sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw== + dependencies: + readable-stream "^3.6.0" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +regenerator-runtime@^0.13.3: + version "0.13.11" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" + integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +retry@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" + integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== + +rimraf@^2.6.3: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-stable-stringify@^2.3.1: + version "2.4.3" + resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz#138c84b6f6edb3db5f8ef3ef7115b8f55ccbf886" + integrity sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g== + +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sax@>=0.6.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.3.0.tgz#a5dbe77db3be05c9d1ee7785dbd3ea9de51593d0" + integrity sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA== + +seek-bzip@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/seek-bzip/-/seek-bzip-1.0.6.tgz#35c4171f55a680916b52a07859ecf3b5857f21c4" + integrity sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ== + dependencies: + commander "^2.8.1" + +selderee@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/selderee/-/selderee-0.11.0.tgz#6af0c7983e073ad3e35787ffe20cefd9daf0ec8a" + integrity sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA== + dependencies: + parseley "^0.12.0" + +semver@^5.7.1: + version "5.7.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" + integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== + +semver@^6.0.0: + version "6.3.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== + +semver@^7.3.5, semver@^7.5.4: + version "7.6.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.0.tgz#1a46a4db4bffcccd97b743b5005c8325f23d4e2d" + integrity sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg== + dependencies: + lru-cache "^6.0.0" + +semver@^7.6.3: + version "7.6.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" + integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== + +semver@~7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" + integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== + +send@0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" + integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== + dependencies: + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "2.0.0" + mime "1.6.0" + ms "2.1.3" + on-finished "2.4.1" + range-parser "~1.2.1" + statuses "2.0.1" + +serve-static@1.15.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" + integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.18.0" + +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== + +set-function-length@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" + integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== + dependencies: + define-data-property "^1.1.4" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + gopd "^1.0.1" + has-property-descriptors "^1.0.2" + +setimmediate@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +sharp@^0.32.0: + version "0.32.6" + resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.32.6.tgz#6ad30c0b7cd910df65d5f355f774aa4fce45732a" + integrity sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w== + dependencies: + color "^4.2.3" + detect-libc "^2.0.2" + node-addon-api "^6.1.0" + prebuild-install "^7.1.1" + semver "^7.5.4" + simple-get "^4.0.1" + tar-fs "^3.0.4" + tunnel-agent "^0.6.0" + +sharp@^0.33.5: + version "0.33.5" + resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.33.5.tgz#13e0e4130cc309d6a9497596715240b2ec0c594e" + integrity sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw== + dependencies: + color "^4.2.3" + detect-libc "^2.0.3" + semver "^7.6.3" + optionalDependencies: + "@img/sharp-darwin-arm64" "0.33.5" + "@img/sharp-darwin-x64" "0.33.5" + "@img/sharp-libvips-darwin-arm64" "1.0.4" + "@img/sharp-libvips-darwin-x64" "1.0.4" + "@img/sharp-libvips-linux-arm" "1.0.5" + "@img/sharp-libvips-linux-arm64" "1.0.4" + "@img/sharp-libvips-linux-s390x" "1.0.4" + "@img/sharp-libvips-linux-x64" "1.0.4" + "@img/sharp-libvips-linuxmusl-arm64" "1.0.4" + "@img/sharp-libvips-linuxmusl-x64" "1.0.4" + "@img/sharp-linux-arm" "0.33.5" + "@img/sharp-linux-arm64" "0.33.5" + "@img/sharp-linux-s390x" "0.33.5" + "@img/sharp-linux-x64" "0.33.5" + "@img/sharp-linuxmusl-arm64" "0.33.5" + "@img/sharp-linuxmusl-x64" "0.33.5" + "@img/sharp-wasm32" "0.33.5" + "@img/sharp-win32-ia32" "0.33.5" + "@img/sharp-win32-x64" "0.33.5" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +side-channel@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2" + integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA== + dependencies: + call-bind "^1.0.7" + es-errors "^1.3.0" + get-intrinsic "^1.2.4" + object-inspect "^1.13.1" + +signal-exit@^3.0.0: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +simple-concat@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" + integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== + +simple-get@^4.0.0, simple-get@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-4.0.1.tgz#4a39db549287c979d352112fa03fd99fd6bc3543" + integrity sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA== + dependencies: + decompress-response "^6.0.0" + once "^1.3.1" + simple-concat "^1.0.0" + +simple-swizzle@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" + integrity sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg== + dependencies: + is-arrayish "^0.3.1" + +simple-update-notifier@^1.0.7: + version "1.1.0" + resolved "https://registry.yarnpkg.com/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz#67694c121de354af592b347cdba798463ed49c82" + integrity sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg== + dependencies: + semver "~7.0.0" + +slugify@^1.6.6: + version "1.6.6" + resolved "https://registry.yarnpkg.com/slugify/-/slugify-1.6.6.tgz#2d4ac0eacb47add6af9e04d3be79319cbcc7924b" + integrity sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw== + +smart-buffer@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" + integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== + +socks-proxy-agent@^8.0.2: + version "8.0.3" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-8.0.3.tgz#6b2da3d77364fde6292e810b496cb70440b9b89d" + integrity sha512-VNegTZKhuGq5vSD6XNKlbqWhyt/40CgoEw8XxD6dhnm8Jq9IEa3nIa4HwnM8XOqU0CdB0BwWVXusqiFXfHB3+A== + dependencies: + agent-base "^7.1.1" + debug "^4.3.4" + socks "^2.7.1" + +socks@^2.7.1: + version "2.8.3" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.8.3.tgz#1ebd0f09c52ba95a09750afe3f3f9f724a800cb5" + integrity sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw== + dependencies: + ip-address "^9.0.5" + smart-buffer "^4.2.0" + +source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +sprintf-js@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.3.tgz#4914b903a2f8b685d17fdf78a70e917e872e444a" + integrity sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA== + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== + +stack-trace@0.0.x: + version "0.0.10" + resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" + integrity sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg== + +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + +streamx@^2.15.0, streamx@^2.16.1: + version "2.16.1" + resolved "https://registry.yarnpkg.com/streamx/-/streamx-2.16.1.tgz#2b311bd34832f08aa6bb4d6a80297c9caef89614" + integrity sha512-m9QYj6WygWyWa3H1YY69amr4nVgy61xfjys7xO7kviL5rfIEc2naf+ewFiOA+aEJD7y0JO3h2GoiUv4TDwEGzQ== + dependencies: + fast-fifo "^1.1.0" + queue-tick "^1.0.1" + optionalDependencies: + bare-events "^2.2.0" + +"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-dirs@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/strip-dirs/-/strip-dirs-2.1.0.tgz#4987736264fc344cf20f6c34aca9d13d1d4ed6c5" + integrity sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g== + dependencies: + is-natural-number "^4.0.1" + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== + +strtok3@^6.2.4: + version "6.3.0" + resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-6.3.0.tgz#358b80ffe6d5d5620e19a073aa78ce947a90f9a0" + integrity sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw== + dependencies: + "@tokenizer/token" "^0.3.0" + peek-readable "^4.1.0" + +supports-color@^5.3.0, supports-color@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +tar-fs@3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-3.0.4.tgz#a21dc60a2d5d9f55e0089ccd78124f1d3771dbbf" + integrity sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w== + dependencies: + mkdirp-classic "^0.5.2" + pump "^3.0.0" + tar-stream "^3.1.5" + +tar-fs@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" + integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== + dependencies: + chownr "^1.1.1" + mkdirp-classic "^0.5.2" + pump "^3.0.0" + tar-stream "^2.1.4" + +tar-fs@^3.0.4: + version "3.0.6" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-3.0.6.tgz#eaccd3a67d5672f09ca8e8f9c3d2b89fa173f217" + integrity sha512-iokBDQQkUyeXhgPYaZxmczGPhnhXZ0CmrqI+MOb/WFGS9DW5wnfrLgtjUJBvz50vQ3qfRwJ62QVoCFu8mPVu5w== + dependencies: + pump "^3.0.0" + tar-stream "^3.1.5" + optionalDependencies: + bare-fs "^2.1.1" + bare-path "^2.1.0" + +tar-stream@^1.5.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555" + integrity sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A== + dependencies: + bl "^1.0.0" + buffer-alloc "^1.2.0" + end-of-stream "^1.0.0" + fs-constants "^1.0.0" + readable-stream "^2.3.0" + to-buffer "^1.1.1" + xtend "^4.0.0" + +tar-stream@^2.1.4: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" + integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== + dependencies: + bl "^4.0.3" + end-of-stream "^1.4.1" + fs-constants "^1.0.0" + inherits "^2.0.3" + readable-stream "^3.1.1" + +tar-stream@^3.1.5: + version "3.1.7" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-3.1.7.tgz#24b3fb5eabada19fe7338ed6d26e5f7c482e792b" + integrity sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ== + dependencies: + b4a "^1.6.4" + fast-fifo "^1.2.0" + streamx "^2.15.0" + +tar@^6.1.11: + version "6.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.1.tgz#717549c541bc3c2af15751bea94b1dd068d4b03a" + integrity sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A== + dependencies: + chownr "^2.0.0" + fs-minipass "^2.0.0" + minipass "^5.0.0" + minizlib "^2.1.1" + mkdirp "^1.0.3" + yallist "^4.0.0" + +tesseract.js-core@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/tesseract.js-core/-/tesseract.js-core-6.0.0.tgz#6f25da94f70f8e8f02aff47a43be61d49e6f67c3" + integrity sha512-1Qncm/9oKM7xgrQXZXNB+NRh19qiXGhxlrR8EwFbK5SaUbPZnS5OMtP/ghtqfd23hsr1ZvZbZjeuAGcMxd/ooA== + +tesseract.js@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/tesseract.js/-/tesseract.js-6.0.0.tgz#62ff7fffc8833b5810430a4067785e49d5ca8e7f" + integrity sha512-tqYCod1HwJzkeZw1l6XWx+ly2hhisGcBtak9MArhYwDAxL0NgeVhLJcUjqPxZMQtpgtVUzWcpZPryi+hnaQGVw== + dependencies: + bmp-js "^0.1.0" + idb-keyval "^6.2.0" + is-url "^1.2.4" + node-fetch "^2.6.9" + opencollective-postinstall "^2.0.3" + regenerator-runtime "^0.13.3" + tesseract.js-core "^6.0.0" + wasm-feature-detect "^1.2.11" + zlibjs "^0.3.1" + +text-hex@1.0.x: + version "1.0.0" + resolved "https://registry.yarnpkg.com/text-hex/-/text-hex-1.0.0.tgz#69dc9c1b17446ee79a92bf5b884bb4b9127506f5" + integrity sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg== + +through@^2.3.8: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== + +tlds@1.252.0: + version "1.252.0" + resolved "https://registry.yarnpkg.com/tlds/-/tlds-1.252.0.tgz#71d9617f4ef4cc7347843bee72428e71b8b0f419" + integrity sha512-GA16+8HXvqtfEnw/DTcwB0UU354QE1n3+wh08oFjr6Znl7ZLAeUgYzCcK+/CCrOyE0vnHR8/pu3XXG3vDijXpQ== + +to-buffer@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80" + integrity sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +token-types@^4.1.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/token-types/-/token-types-4.2.1.tgz#0f897f03665846982806e138977dbe72d44df753" + integrity sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ== + dependencies: + "@tokenizer/token" "^0.3.0" + ieee754 "^1.2.1" + +touch@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" + integrity sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA== + dependencies: + nopt "~1.0.10" + +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== + +triple-beam@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.4.1.tgz#6fde70271dc6e5d73ca0c3b24e2d92afb7441984" + integrity sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg== + +ts-type@>=2: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ts-type/-/ts-type-3.0.1.tgz#b52e7623065e0beb43c77c426347d85cf81dff84" + integrity sha512-cleRydCkBGBFQ4KAvLH0ARIkciduS745prkGVVxPGvcRGhMMoSJUB7gNR1ByKhFTEYrYRg2CsMRGYnqp+6op+g== + dependencies: + "@types/node" "*" + tslib ">=2" + typedarray-dts "^1.0.0" + +tslib@>=2, tslib@^2.0.1, tslib@^2.5.0, tslib@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" + integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== + +tslib@^2.4.0: + version "2.8.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" + integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== + dependencies: + safe-buffer "^5.0.1" + +type-detect@^4.0.0: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +typedarray-dts@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typedarray-dts/-/typedarray-dts-1.0.0.tgz#9dec9811386dbfba964c295c2606cf9a6b982d06" + integrity sha512-Ka0DBegjuV9IPYFT1h0Qqk5U4pccebNIJCGl8C5uU7xtOs+jpJvKGAY4fHGK25hTmXZOEUl9Cnsg5cS6K/b5DA== + +uc.micro@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-2.1.0.tgz#f8d3f7d0ec4c3dea35a7e3c8efa4cb8b45c9e7ee" + integrity sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A== + +unbzip2-stream@1.4.3, unbzip2-stream@^1.0.9: + version "1.4.3" + resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz#b0da04c4371311df771cdc215e87f2130991ace7" + integrity sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg== + dependencies: + buffer "^5.2.1" + through "^2.3.8" + +undefsafe@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c" + integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA== + +underscore@^1.13.1: + version "1.13.6" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.6.tgz#04786a1f589dc6c09f761fc5f45b89e935136441" + integrity sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A== + +undici-types@~5.26.4: + version "5.26.5" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" + integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== + +undici@^5.19.1: + version "5.28.4" + resolved "https://registry.yarnpkg.com/undici/-/undici-5.28.4.tgz#6b280408edb6a1a604a9b20340f45b422e373068" + integrity sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g== + dependencies: + "@fastify/busboy" "^2.0.0" + +universalify@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" + integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== + +url-pattern@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/url-pattern/-/url-pattern-1.0.3.tgz#0409292471b24f23c50d65a47931793d2b5acfc1" + integrity sha512-uQcEj/2puA4aq1R3A2+VNVBgaWYR24FdWjl7VNW83rnWftlhyzOZ/tBjezRiC2UkIzuxC8Top3IekN3vUf1WxA== + +urlpattern-polyfill@9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/urlpattern-polyfill/-/urlpattern-polyfill-9.0.0.tgz#bc7e386bb12fd7898b58d1509df21d3c29ab3460" + integrity sha512-WHN8KDQblxd32odxeIgo83rdVDE2bvdkb86it7bMhYZwWKJz0+O0RK/eZiHYnM+zgt/U7hAHOlCQGfjjvSkw2g== + +util-deprecate@^1.0.1, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== + +uuid@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-10.0.0.tgz#5a95aa454e6e002725c79055fd42aaba30ca6294" + integrity sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ== + +uuid@^9.0.0: + version "9.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30" + integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== + +vary@^1, vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== + +wasm-feature-detect@^1.2.11: + version "1.8.0" + resolved "https://registry.yarnpkg.com/wasm-feature-detect/-/wasm-feature-detect-1.8.0.tgz#4e9f55b0a64d801f372fbb0324ed11ad3abd0c78" + integrity sha512-zksaLKM2fVlnB5jQQDqKXXwYHLQUVH9es+5TOOHwGOVJOCeRBCiPjwSg+3tN2AdTCzjgli4jijCH290kXb/zWQ== + +wavefile@^11.0.0: + version "11.0.0" + resolved "https://registry.yarnpkg.com/wavefile/-/wavefile-11.0.0.tgz#9302165874327ff63a704d00b154c753eaa1b8e7" + integrity sha512-/OBiAALgWU24IG7sC84cDO/KfFuvajWc5Uec0oV2zrpOOZZDgGdOwHwgEzOrwh8jkubBk7PtZfQBIcI1OaE5Ng== + +web-streams-polyfill@4.0.0-beta.3: + version "4.0.0-beta.3" + resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz#2898486b74f5156095e473efe989dcf185047a38" + integrity sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug== + +web-streams-polyfill@^3.2.1: + version "3.3.3" + resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz#2073b91a2fdb1fbfbd401e7de0ac9f8214cecb4b" + integrity sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw== + +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== + +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + +which@^1.1.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wide-align@^1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" + integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== + dependencies: + string-width "^1.0.2 || 2 || 3 || 4" + +winston-transport@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.7.0.tgz#e302e6889e6ccb7f383b926df6936a5b781bd1f0" + integrity sha512-ajBj65K5I7denzer2IYW6+2bNIVqLGDHqDw3Ow8Ohh+vdW+rv4MZ6eiDvHoKhfJFZ2auyN8byXieDDJ96ViONg== + dependencies: + logform "^2.3.2" + readable-stream "^3.6.0" + triple-beam "^1.3.0" + +winston@^3.13.0: + version "3.13.0" + resolved "https://registry.yarnpkg.com/winston/-/winston-3.13.0.tgz#e76c0d722f78e04838158c61adc1287201de7ce3" + integrity sha512-rwidmA1w3SE4j0E5MuIufFhyJPBDG7Nu71RkZor1p2+qHvJSZ9GYDA81AyleQcZbh/+V6HjeBdfnTZJm9rSeQQ== + dependencies: + "@colors/colors" "^1.6.0" + "@dabh/diagnostics" "^2.0.2" + async "^3.2.3" + is-stream "^2.0.0" + logform "^2.4.0" + one-time "^1.0.0" + readable-stream "^3.4.0" + safe-stable-stringify "^2.3.1" + stack-trace "0.0.x" + triple-beam "^1.3.0" + winston-transport "^4.7.0" + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +ws@8.14.2: + version "8.14.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.14.2.tgz#6c249a806eb2db7a20d26d51e7709eab7b2e6c7f" + integrity sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g== + +"xlsx@https://cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz": + version "0.20.2" + resolved "https://cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz#0f64eeed3f1a46e64724620c3553f2dbd3cd2d7d" + +xml2js@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.6.2.tgz#dd0b630083aa09c161e25a4d0901e2b2a929b499" + integrity sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA== + dependencies: + sax ">=0.6.0" + xmlbuilder "~11.0.0" + +xmlbuilder@^10.0.0: + version "10.1.1" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-10.1.1.tgz#8cae6688cc9b38d850b7c8d3c0a4161dcaf475b0" + integrity sha512-OyzrcFLL/nb6fMGHbiRDuPup9ljBycsdCypwuyg5AAHvyWzGfChJpCXMG88AGTIMFhGZ9RccFN1e6lhg3hkwKg== + +xmlbuilder@~11.0.0: + version "11.0.1" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" + integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== + +xtend@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yaml@^2.2.1: + version "2.4.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.4.2.tgz#7a2b30f2243a5fc299e1f14ca58d475ed4bc5362" + integrity sha512-B3VqDZ+JAg1nZpaEmWtTXUlBneoGx6CPM9b0TENK6aoSu5t73dItudwdgmi6tHlIZZId4dZ9skcAQ2UbcyAeVA== + +yargs-parser@^21.1.1: + version "21.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" + integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== + +yargs@17.7.2: + version "17.7.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" + integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== + dependencies: + cliui "^8.0.1" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.1.1" + +yauzl@^2.10.0, yauzl@^2.4.2: + version "2.10.0" + resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" + integrity sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g== + dependencies: + buffer-crc32 "~0.2.3" + fd-slicer "~1.1.0" + +youtubei.js@^9.1.0: + version "9.4.0" + resolved "https://registry.yarnpkg.com/youtubei.js/-/youtubei.js-9.4.0.tgz#ccccaf4a295b96e3e17134a66730bbc82461594b" + integrity sha512-8plCOZD2WabqWSEgZU3RjzigIIeR7sF028EERJENYrC9xO/6awpLMZfeoE1gNrNEbKcA+bzbMvonqlvBdxGdKg== + dependencies: + jintr "^1.1.0" + tslib "^2.5.0" + undici "^5.19.1" + +zlibjs@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/zlibjs/-/zlibjs-0.3.1.tgz#50197edb28a1c42ca659cc8b4e6a9ddd6d444554" + integrity sha512-+J9RrgTKOmlxFSDHo0pI1xM6BLVUv+o0ZT9ANtCxGkjIVCCUdx9alUF8Gm+dGLKbkkkidWIHFDZHDMpfITt4+w== + +zod-to-json-schema@^3.22.3, zod-to-json-schema@^3.22.5: + version "3.23.0" + resolved "https://registry.yarnpkg.com/zod-to-json-schema/-/zod-to-json-schema-3.23.0.tgz#4fc60e88d3c709eedbfaae3f92f8a7bf786469f2" + integrity sha512-az0uJ243PxsRIa2x1WmNE/pnuA05gUq/JB8Lwe1EDCCL/Fz9MgjYQ0fPlyc2Tcv6aF2ZA7WM5TWaRZVEFaAIag== + +zod@^3.22.3, zod@^3.22.4: + version "3.23.5" + resolved "https://registry.yarnpkg.com/zod/-/zod-3.23.5.tgz#c7b7617d017d4a2f21852f533258d26a9a5ae09f" + integrity sha512-fkwiq0VIQTksNNA131rDOsVJcns0pfVUjHzLrNBiF/O/Xxb5lQyEXkhZWcJ7npWsYlvs+h0jFWXXy4X46Em1JA== diff --git a/docker/.env.example b/docker/.env.example new file mode 100644 index 0000000000000000000000000000000000000000..421d05368c528e77f032bf140a93ec44d1f54aa9 --- /dev/null +++ b/docker/.env.example @@ -0,0 +1,372 @@ +SERVER_PORT=3001 +STORAGE_DIR="/app/server/storage" +UID='1000' +GID='1000' +# SIG_KEY='passphrase' # Please generate random string at least 32 chars long. +# SIG_SALT='salt' # Please generate random string at least 32 chars long. +# JWT_SECRET="my-random-string-for-seeding" # Only needed if AUTH_TOKEN is set. Please generate random string at least 12 chars long. +# JWT_EXPIRY="30d" # (optional) https://docs.anythingllm.com/configuration#custom-ttl-for-sessions + +########################################### +######## LLM API SElECTION ################ +########################################### +# LLM_PROVIDER='openai' +# OPEN_AI_KEY= +# OPEN_MODEL_PREF='gpt-4o' + +# LLM_PROVIDER='gemini' +# GEMINI_API_KEY= +# GEMINI_LLM_MODEL_PREF='gemini-2.0-flash-lite' + +# LLM_PROVIDER='azure' +# AZURE_OPENAI_ENDPOINT= +# AZURE_OPENAI_KEY= +# OPEN_MODEL_PREF='my-gpt35-deployment' # This is the "deployment" on Azure you want to use. Not the base model. +# EMBEDDING_MODEL_PREF='embedder-model' # This is the "deployment" on Azure you want to use for embeddings. Not the base model. Valid base model is text-embedding-ada-002 + +# LLM_PROVIDER='anthropic' +# ANTHROPIC_API_KEY=sk-ant-xxxx +# ANTHROPIC_MODEL_PREF='claude-2' + +# LLM_PROVIDER='lmstudio' +# LMSTUDIO_BASE_PATH='http://your-server:1234/v1' +# LMSTUDIO_MODEL_PREF='Loaded from Chat UI' # this is a bug in LMStudio 0.2.17 +# LMSTUDIO_MODEL_TOKEN_LIMIT=4096 + +# LLM_PROVIDER='localai' +# LOCAL_AI_BASE_PATH='http://host.docker.internal:8080/v1' +# LOCAL_AI_MODEL_PREF='luna-ai-llama2' +# LOCAL_AI_MODEL_TOKEN_LIMIT=4096 +# LOCAL_AI_API_KEY="sk-123abc" + +# LLM_PROVIDER='ollama' +# OLLAMA_BASE_PATH='http://host.docker.internal:11434' +# OLLAMA_MODEL_PREF='llama2' +# OLLAMA_MODEL_TOKEN_LIMIT=4096 +# OLLAMA_AUTH_TOKEN='your-ollama-auth-token-here (optional, only for ollama running behind auth - Bearer token)' + +# LLM_PROVIDER='togetherai' +# TOGETHER_AI_API_KEY='my-together-ai-key' +# TOGETHER_AI_MODEL_PREF='mistralai/Mixtral-8x7B-Instruct-v0.1' + +# LLM_PROVIDER='mistral' +# MISTRAL_API_KEY='example-mistral-ai-api-key' +# MISTRAL_MODEL_PREF='mistral-tiny' + +# LLM_PROVIDER='perplexity' +# PERPLEXITY_API_KEY='my-perplexity-key' +# PERPLEXITY_MODEL_PREF='codellama-34b-instruct' + +# LLM_PROVIDER='openrouter' +# OPENROUTER_API_KEY='my-openrouter-key' +# OPENROUTER_MODEL_PREF='openrouter/auto' + +# LLM_PROVIDER='huggingface' +# HUGGING_FACE_LLM_ENDPOINT=https://uuid-here.us-east-1.aws.endpoints.huggingface.cloud +# HUGGING_FACE_LLM_API_KEY=hf_xxxxxx +# HUGGING_FACE_LLM_TOKEN_LIMIT=8000 + +# LLM_PROVIDER='groq' +# GROQ_API_KEY=gsk_abcxyz +# GROQ_MODEL_PREF=llama3-8b-8192 + +# LLM_PROVIDER='koboldcpp' +# KOBOLD_CPP_BASE_PATH='http://127.0.0.1:5000/v1' +# KOBOLD_CPP_MODEL_PREF='koboldcpp/codellama-7b-instruct.Q4_K_S' +# KOBOLD_CPP_MODEL_TOKEN_LIMIT=4096 + +# LLM_PROVIDER='textgenwebui' +# TEXT_GEN_WEB_UI_BASE_PATH='http://127.0.0.1:5000/v1' +# TEXT_GEN_WEB_UI_TOKEN_LIMIT=4096 +# TEXT_GEN_WEB_UI_API_KEY='sk-123abc' + +# LLM_PROVIDER='generic-openai' +# GENERIC_OPEN_AI_BASE_PATH='http://proxy.url.openai.com/v1' +# GENERIC_OPEN_AI_MODEL_PREF='gpt-3.5-turbo' +# GENERIC_OPEN_AI_MODEL_TOKEN_LIMIT=4096 +# GENERIC_OPEN_AI_API_KEY=sk-123abc + +# LLM_PROVIDER='litellm' +# LITE_LLM_MODEL_PREF='gpt-3.5-turbo' +# LITE_LLM_MODEL_TOKEN_LIMIT=4096 +# LITE_LLM_BASE_PATH='http://127.0.0.1:4000' +# LITE_LLM_API_KEY='sk-123abc' + +# LLM_PROVIDER='novita' +# NOVITA_LLM_API_KEY='your-novita-api-key-here' check on https://novita.ai/settings/key-management +# NOVITA_LLM_MODEL_PREF='deepseek/deepseek-r1' + +# LLM_PROVIDER='cometapi' +# COMETAPI_LLM_API_KEY='your-cometapi-api-key-here' # Get one at https://api.cometapi.com/console/token +# COMETAPI_LLM_MODEL_PREF='gpt-5-mini' +# COMETAPI_LLM_TIMEOUT_MS=500 # Optional; stream idle timeout in ms (min 500ms) + +# LLM_PROVIDER='cohere' +# COHERE_API_KEY= +# COHERE_MODEL_PREF='command-r' + +# LLM_PROVIDER='bedrock' +# AWS_BEDROCK_LLM_ACCESS_KEY_ID= +# AWS_BEDROCK_LLM_ACCESS_KEY= +# AWS_BEDROCK_LLM_REGION=us-west-2 +# AWS_BEDROCK_LLM_MODEL_PREFERENCE=meta.llama3-1-8b-instruct-v1:0 +# AWS_BEDROCK_LLM_MODEL_TOKEN_LIMIT=8191 +# AWS_BEDROCK_LLM_CONNECTION_METHOD=iam +# AWS_BEDROCK_LLM_MAX_OUTPUT_TOKENS=4096 +# AWS_BEDROCK_LLM_SESSION_TOKEN= # Only required if CONNECTION_METHOD is 'sessionToken' + +# LLM_PROVIDER='fireworksai' +# FIREWORKS_AI_LLM_API_KEY='my-fireworks-ai-key' +# FIREWORKS_AI_LLM_MODEL_PREF='accounts/fireworks/models/llama-v3p1-8b-instruct' + +# LLM_PROVIDER='apipie' +# APIPIE_LLM_API_KEY='sk-123abc' +# APIPIE_LLM_MODEL_PREF='openrouter/llama-3.1-8b-instruct' + +# LLM_PROVIDER='xai' +# XAI_LLM_API_KEY='xai-your-api-key-here' +# XAI_LLM_MODEL_PREF='grok-beta' + +# LLM_PROVIDER='nvidia-nim' +# NVIDIA_NIM_LLM_BASE_PATH='http://127.0.0.1:8000' +# NVIDIA_NIM_LLM_MODEL_PREF='meta/llama-3.2-3b-instruct' + +# LLM_PROVIDER='deepseek' +# DEEPSEEK_API_KEY='your-deepseek-api-key-here' +# DEEPSEEK_MODEL_PREF='deepseek-chat' + +# LLM_PROVIDER='ppio' +# PPIO_API_KEY='your-ppio-api-key-here' +# PPIO_MODEL_PREF=deepseek/deepseek-v3/community + +# LLM_PROVIDER='moonshotai' +# MOONSHOT_AI_API_KEY='your-moonshot-api-key-here' +# MOONSHOT_AI_MODEL_PREF='moonshot-v1-32k' + +########################################### +######## Embedding API SElECTION ########## +########################################### +# This will be the assumed default embedding seleciton and model +# EMBEDDING_ENGINE='native' +# EMBEDDING_MODEL_PREF='Xenova/all-MiniLM-L6-v2' + +# Only used if you are using an LLM that does not natively support embedding (openai or Azure) +# EMBEDDING_ENGINE='openai' +# OPEN_AI_KEY=sk-xxxx +# EMBEDDING_MODEL_PREF='text-embedding-ada-002' + +# EMBEDDING_ENGINE='azure' +# AZURE_OPENAI_ENDPOINT= +# AZURE_OPENAI_KEY= +# EMBEDDING_MODEL_PREF='my-embedder-model' # This is the "deployment" on Azure you want to use for embeddings. Not the base model. Valid base model is text-embedding-ada-002 + +# EMBEDDING_ENGINE='localai' +# EMBEDDING_BASE_PATH='http://localhost:8080/v1' +# EMBEDDING_MODEL_PREF='text-embedding-ada-002' +# EMBEDDING_MODEL_MAX_CHUNK_LENGTH=1000 # The max chunk size in chars a string to embed can be + +# EMBEDDING_ENGINE='ollama' +# EMBEDDING_BASE_PATH='http://host.docker.internal:11434' +# EMBEDDING_MODEL_PREF='nomic-embed-text:latest' +# EMBEDDING_MODEL_MAX_CHUNK_LENGTH=8192 + +# EMBEDDING_ENGINE='lmstudio' +# EMBEDDING_BASE_PATH='https://host.docker.internal:1234/v1' +# EMBEDDING_MODEL_PREF='nomic-ai/nomic-embed-text-v1.5-GGUF/nomic-embed-text-v1.5.Q4_0.gguf' +# EMBEDDING_MODEL_MAX_CHUNK_LENGTH=8192 + +# EMBEDDING_ENGINE='cohere' +# COHERE_API_KEY= +# EMBEDDING_MODEL_PREF='embed-english-v3.0' + +# EMBEDDING_ENGINE='voyageai' +# VOYAGEAI_API_KEY= +# EMBEDDING_MODEL_PREF='voyage-large-2-instruct' + +# EMBEDDING_ENGINE='litellm' +# EMBEDDING_MODEL_PREF='text-embedding-ada-002' +# EMBEDDING_MODEL_MAX_CHUNK_LENGTH=8192 +# LITE_LLM_BASE_PATH='http://127.0.0.1:4000' +# LITE_LLM_API_KEY='sk-123abc' + +# EMBEDDING_ENGINE='generic-openai' +# EMBEDDING_MODEL_PREF='text-embedding-ada-002' +# EMBEDDING_MODEL_MAX_CHUNK_LENGTH=8192 +# EMBEDDING_BASE_PATH='http://127.0.0.1:4000' +# GENERIC_OPEN_AI_EMBEDDING_API_KEY='sk-123abc' +# GENERIC_OPEN_AI_EMBEDDING_MAX_CONCURRENT_CHUNKS=500 +# GENERIC_OPEN_AI_EMBEDDING_API_DELAY_MS=1000 + +# EMBEDDING_ENGINE='gemini' +# GEMINI_EMBEDDING_API_KEY= +# EMBEDDING_MODEL_PREF='text-embedding-004' + +########################################### +######## Vector Database Selection ######## +########################################### +# Enable all below if you are using vector database: LanceDB. +# VECTOR_DB="lancedb" + +# Enable all below if you are using vector database: Weaviate. +# VECTOR_DB="pgvector" +# PGVECTOR_CONNECTION_STRING="postgresql://dbuser:dbuserpass@localhost:5432/yourdb" +# PGVECTOR_TABLE_NAME="anythingllm_vectors" # optional, but can be defined + +# Enable all below if you are using vector database: Chroma. +# VECTOR_DB="chroma" +# CHROMA_ENDPOINT='http://host.docker.internal:8000' +# CHROMA_API_HEADER="X-Api-Key" +# CHROMA_API_KEY="sk-123abc" + +# Enable all below if you are using vector database: Chroma Cloud. +# VECTOR_DB="chromacloud" +# CHROMACLOUD_API_KEY="ck-your-api-key" +# CHROMACLOUD_TENANT= +# CHROMACLOUD_DATABASE= + +# Enable all below if you are using vector database: Pinecone. +# VECTOR_DB="pinecone" +# PINECONE_API_KEY= +# PINECONE_INDEX= + +# Enable all below if you are using vector database: Weaviate. +# VECTOR_DB="weaviate" +# WEAVIATE_ENDPOINT="http://localhost:8080" +# WEAVIATE_API_KEY= + +# Enable all below if you are using vector database: Qdrant. +# VECTOR_DB="qdrant" +# QDRANT_ENDPOINT="http://localhost:6333" +# QDRANT_API_KEY= + +# Enable all below if you are using vector database: Milvus. +# VECTOR_DB="milvus" +# MILVUS_ADDRESS="http://localhost:19530" +# MILVUS_USERNAME= +# MILVUS_PASSWORD= + +# Enable all below if you are using vector database: Zilliz Cloud. +# VECTOR_DB="zilliz" +# ZILLIZ_ENDPOINT="https://sample.api.gcp-us-west1.zillizcloud.com" +# ZILLIZ_API_TOKEN=api-token-here + +# Enable all below if you are using vector database: Astra DB. +# VECTOR_DB="astra" +# ASTRA_DB_APPLICATION_TOKEN= +# ASTRA_DB_ENDPOINT= + +########################################### +######## Audio Model Selection ############ +########################################### +# (default) use built-in whisper-small model. +# WHISPER_PROVIDER="local" + +# use openai hosted whisper model. +# WHISPER_PROVIDER="openai" +# OPEN_AI_KEY=sk-xxxxxxxx + +########################################### +######## TTS/STT Model Selection ########## +########################################### +# TTS_PROVIDER="native" + +# TTS_PROVIDER="openai" +# TTS_OPEN_AI_KEY=sk-example +# TTS_OPEN_AI_VOICE_MODEL=nova + +# TTS_PROVIDER="generic-openai" +# TTS_OPEN_AI_COMPATIBLE_KEY=sk-example +# TTS_OPEN_AI_COMPATIBLE_MODEL=tts-1 +# TTS_OPEN_AI_COMPATIBLE_VOICE_MODEL=nova +# TTS_OPEN_AI_COMPATIBLE_ENDPOINT="https://api.openai.com/v1" + +# TTS_PROVIDER="elevenlabs" +# TTS_ELEVEN_LABS_KEY= +# TTS_ELEVEN_LABS_VOICE_MODEL=21m00Tcm4TlvDq8ikWAM # Rachel + +# CLOUD DEPLOYMENT VARIRABLES ONLY +# AUTH_TOKEN="hunter2" # This is the password to your application if remote hosting. +# DISABLE_TELEMETRY="false" + +########################################### +######## PASSWORD COMPLEXITY ############## +########################################### +# Enforce a password schema for your organization users. +# Documentation on how to use https://github.com/kamronbatman/joi-password-complexity +# Default is only 8 char minimum +# PASSWORDMINCHAR=8 +# PASSWORDMAXCHAR=250 +# PASSWORDLOWERCASE=1 +# PASSWORDUPPERCASE=1 +# PASSWORDNUMERIC=1 +# PASSWORDSYMBOL=1 +# PASSWORDREQUIREMENTS=4 + +########################################### +######## ENABLE HTTPS SERVER ############## +########################################### +# By enabling this and providing the path/filename for the key and cert, +# the server will use HTTPS instead of HTTP. +#ENABLE_HTTPS="true" +#HTTPS_CERT_PATH="sslcert/cert.pem" +#HTTPS_KEY_PATH="sslcert/key.pem" + +########################################### +######## AGENT SERVICE KEYS ############### +########################################### + +#------ SEARCH ENGINES ------- +#============================= +#------ Google Search -------- https://programmablesearchengine.google.com/controlpanel/create +# AGENT_GSE_KEY= +# AGENT_GSE_CTX= + +#------ SearchApi.io ----------- https://www.searchapi.io/ +# AGENT_SEARCHAPI_API_KEY= +# AGENT_SEARCHAPI_ENGINE=google + +#------ Serper.dev ----------- https://serper.dev/ +# AGENT_SERPER_DEV_KEY= + +#------ Bing Search ----------- https://portal.azure.com/ +# AGENT_BING_SEARCH_API_KEY= + +#------ Serply.io ----------- https://serply.io/ +# AGENT_SERPLY_API_KEY= + +#------ SearXNG ----------- https://github.com/searxng/searxng +# AGENT_SEARXNG_API_URL= + +#------ Tavily ----------- https://www.tavily.com/ +# AGENT_TAVILY_API_KEY= + +#------ Exa Search ----------- https://www.exa.ai/ +# AGENT_EXA_API_KEY= + +########################################### +######## Other Configurations ############ +########################################### + +# Disable viewing chat history from the UI and frontend APIs. +# See https://docs.anythingllm.com/configuration#disable-view-chat-history for more information. +# DISABLE_VIEW_CHAT_HISTORY=1 + +# Enable simple SSO passthrough to pre-authenticate users from a third party service. +# See https://docs.anythingllm.com/configuration#simple-sso-passthrough for more information. +# SIMPLE_SSO_ENABLED=1 +# SIMPLE_SSO_NO_LOGIN=1 +# SIMPLE_SSO_NO_LOGIN_REDIRECT=https://your-custom-login-url.com (optional) + +# Allow scraping of any IP address in collector - must be string "true" to be enabled +# See https://docs.anythingllm.com/configuration#local-ip-address-scraping for more information. +# COLLECTOR_ALLOW_ANY_IP="true" + +# Specify the target languages for when using OCR to parse images and PDFs. +# This is a comma separated list of language codes as a string. Unsupported languages will be ignored. +# Default is English. See https://tesseract-ocr.github.io/tessdoc/Data-Files-in-different-versions.html for a list of valid language codes. +# TARGET_OCR_LANG=eng,deu,ita,spa,fra,por,rus,nld,tur,hun,pol,ita,spa,fra,por,rus,nld,tur,hun,pol + +# Runtime flags for built-in pupeeteer Chromium instance +# This is only required on Linux machines running AnythingLLM via Docker +# and do not want to use the --cap-add=SYS_ADMIN docker argument +# ANYTHINGLLM_CHROMIUM_ARGS="--no-sandbox,--disable-setuid-sandbox" \ No newline at end of file diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..13c496d04735f6f96bec0912b6fa428c0636b3c7 --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,180 @@ +# Setup base image +FROM ubuntu:jammy-20240627.1 AS base + +# Build arguments +ARG ARG_UID=1000 +ARG ARG_GID=1000 + +FROM base AS build-arm64 +RUN echo "Preparing build of AnythingLLM image for arm64 architecture" + +SHELL ["/bin/bash", "-o", "pipefail", "-c"] + +# Install system dependencies +# hadolint ignore=DL3008,DL3013 +RUN DEBIAN_FRONTEND=noninteractive apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get install -yq --no-install-recommends \ + unzip curl gnupg libgfortran5 libgbm1 tzdata netcat \ + libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 \ + libgcc1 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libx11-6 libx11-xcb1 libxcb1 \ + libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 \ + libxss1 libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release \ + xdg-utils git build-essential ffmpeg && \ + mkdir -p /etc/apt/keyrings && \ + curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg && \ + echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list && \ + apt-get update && \ + # Install node and yarn + apt-get install -yq --no-install-recommends nodejs && \ + curl -LO https://github.com/yarnpkg/yarn/releases/download/v1.22.19/yarn_1.22.19_all.deb \ + && dpkg -i yarn_1.22.19_all.deb \ + && rm yarn_1.22.19_all.deb && \ + # Install uvx (pinned to 0.6.10) for MCP support + curl -LsSf https://astral.sh/uv/0.6.10/install.sh | sh && \ + mv /root/.local/bin/uv /usr/local/bin/uv && \ + mv /root/.local/bin/uvx /usr/local/bin/uvx && \ + echo "Installed uvx! $(uv --version)" && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +# Create a group and user with specific UID and GID +RUN groupadd -g "$ARG_GID" anythingllm && \ + useradd -l -u "$ARG_UID" -m -d /app -s /bin/bash -g anythingllm anythingllm && \ + mkdir -p /app/frontend/ /app/server/ /app/collector/ && chown -R anythingllm:anythingllm /app + +# Copy docker helper scripts +COPY ./docker/docker-entrypoint.sh /usr/local/bin/ +COPY ./docker/docker-healthcheck.sh /usr/local/bin/ +COPY --chown=anythingllm:anythingllm ./docker/.env.example /app/server/.env + +# Ensure the scripts are executable +RUN chmod +x /usr/local/bin/docker-entrypoint.sh && \ + chmod +x /usr/local/bin/docker-healthcheck.sh + +USER anythingllm +WORKDIR /app + +# Puppeteer does not ship with an ARM86 compatible build for Chromium +# so web-scraping would be broken in arm docker containers unless we patch it +# by manually installing a compatible chromedriver. +RUN echo "Need to patch Puppeteer x Chromium support for ARM86 - installing dep!" && \ + curl https://playwright.azureedge.net/builds/chromium/1088/chromium-linux-arm64.zip -o chrome-linux.zip && \ + unzip chrome-linux.zip && \ + rm -rf chrome-linux.zip + +ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true +ENV CHROME_PATH=/app/chrome-linux/chrome +ENV PUPPETEER_EXECUTABLE_PATH=/app/chrome-linux/chrome + +RUN echo "Done running arm64 specific installation steps" + +############################################# + +# amd64-specific stage +FROM base AS build-amd64 +RUN echo "Preparing build of AnythingLLM image for non-ARM architecture" + +SHELL ["/bin/bash", "-o", "pipefail", "-c"] + +# Install system dependencies +# hadolint ignore=DL3008,DL3013 +RUN DEBIAN_FRONTEND=noninteractive apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get install -yq --no-install-recommends \ + curl gnupg libgfortran5 libgbm1 tzdata netcat \ + libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 \ + libgcc1 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libx11-6 libx11-xcb1 libxcb1 \ + libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 \ + libxss1 libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release \ + xdg-utils git build-essential ffmpeg && \ + mkdir -p /etc/apt/keyrings && \ + curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg && \ + echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list && \ + apt-get update && \ + # Install node and yarn + apt-get install -yq --no-install-recommends nodejs && \ + curl -LO https://github.com/yarnpkg/yarn/releases/download/v1.22.19/yarn_1.22.19_all.deb \ + && dpkg -i yarn_1.22.19_all.deb \ + && rm yarn_1.22.19_all.deb && \ + # Install uvx (pinned to 0.6.10) for MCP support + curl -LsSf https://astral.sh/uv/0.6.10/install.sh | sh && \ + mv /root/.local/bin/uv /usr/local/bin/uv && \ + mv /root/.local/bin/uvx /usr/local/bin/uvx && \ + echo "Installed uvx! $(uv --version)" && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +# Create a group and user with specific UID and GID +RUN groupadd -g "$ARG_GID" anythingllm && \ + useradd -l -u "$ARG_UID" -m -d /app -s /bin/bash -g anythingllm anythingllm && \ + mkdir -p /app/frontend/ /app/server/ /app/collector/ && chown -R anythingllm:anythingllm /app + +# Copy docker helper scripts +COPY ./docker/docker-entrypoint.sh /usr/local/bin/ +COPY ./docker/docker-healthcheck.sh /usr/local/bin/ +COPY --chown=anythingllm:anythingllm ./docker/.env.example /app/server/.env + +# Ensure the scripts are executable +RUN chmod +x /usr/local/bin/docker-entrypoint.sh && \ + chmod +x /usr/local/bin/docker-healthcheck.sh + +############################################# +# COMMON BUILD FLOW FOR ALL ARCHS +############################################# + +# hadolint ignore=DL3006 +FROM build-${TARGETARCH} AS build +RUN echo "Running common build flow of AnythingLLM image for all architectures" + +USER anythingllm +WORKDIR /app + +# Install & Build frontend layer +FROM build AS frontend-build +COPY --chown=anythingllm:anythingllm ./frontend /app/frontend/ +WORKDIR /app/frontend +RUN yarn install --network-timeout 100000 && yarn cache clean +RUN yarn build && \ + cp -r dist /tmp/frontend-build && \ + rm -rf * && \ + cp -r /tmp/frontend-build dist && \ + rm -rf /tmp/frontend-build +WORKDIR /app + +# Install server layer +# Also pull and build collector deps (chromium issues prevent bad bindings) +FROM build AS backend-build +COPY --chown=anythingllm:anythingllm ./server /app/server/ +WORKDIR /app/server +RUN yarn install --production --network-timeout 100000 && yarn cache clean +WORKDIR /app + +# Install collector dependencies +COPY --chown=anythingllm:anythingllm ./collector/ ./collector/ +WORKDIR /app/collector +ENV PUPPETEER_DOWNLOAD_BASE_URL=https://storage.googleapis.com/chrome-for-testing-public +RUN yarn install --production --network-timeout 100000 && yarn cache clean + +WORKDIR /app +USER anythingllm + +# Since we are building from backend-build we just need to move built frontend into server/public +FROM backend-build AS production-build +WORKDIR /app +COPY --chown=anythingllm:anythingllm --from=frontend-build /app/frontend/dist /app/server/public +USER root +RUN chown -R anythingllm:anythingllm /app/server && \ + chown -R anythingllm:anythingllm /app/collector +USER anythingllm + +# Setup the environment +ENV NODE_ENV=production +ENV ANYTHING_LLM_RUNTIME=docker +ENV DEPLOYMENT_VERSION=1.8.5 + +# Setup the healthcheck +HEALTHCHECK --interval=1m --timeout=10s --start-period=1m \ + CMD /bin/bash /usr/local/bin/docker-healthcheck.sh || exit 1 + +# Run the server +# CMD ["sh", "-c", "tail -f /dev/null"] # For development: keep container open +ENTRYPOINT ["/bin/bash", "/usr/local/bin/docker-entrypoint.sh"] diff --git a/docker/HOW_TO_USE_DOCKER.md b/docker/HOW_TO_USE_DOCKER.md new file mode 100644 index 0000000000000000000000000000000000000000..2eeaee060f9647036a0cc79b175a1eec776b3914 --- /dev/null +++ b/docker/HOW_TO_USE_DOCKER.md @@ -0,0 +1,209 @@ +# How to use Dockerized Anything LLM + +Use the Dockerized version of AnythingLLM for a much faster and complete startup of AnythingLLM. + +### Minimum Requirements + +> [!TIP] +> Running AnythingLLM on AWS/GCP/Azure? +> You should aim for at least 2GB of RAM. Disk storage is proportional to however much data +> you will be storing (documents, vectors, models, etc). Minimum 10GB recommended. + +- `docker` installed on your machine +- `yarn` and `node` on your machine +- access to an LLM running locally or remotely + +\*AnythingLLM by default uses a built-in vector database powered by [LanceDB](https://github.com/lancedb/lancedb) + +\*AnythingLLM by default embeds text on instance privately [Learn More](../server/storage/models/README.md) + +## Recommend way to run dockerized AnythingLLM! + +> [!IMPORTANT] +> If you are running another service on localhost like Chroma, LocalAi, or LMStudio +> you will need to use http://host.docker.internal:xxxx to access the service from within +> the docker container using AnythingLLM as `localhost:xxxx` will not resolve for the host system. +> +> **Requires** Docker v18.03+ on Win/Mac and 20.10+ on Linux/Ubuntu for host.docker.internal to resolve! +> +> _Linux_: add `--add-host=host.docker.internal:host-gateway` to docker run command for this to resolve. +> +> eg: Chroma host URL running on localhost:8000 on host machine needs to be http://host.docker.internal:8000 +> when used in AnythingLLM. + +> [!TIP] +> It is best to mount the containers storage volume to a folder on your host machine +> so that you can pull in future updates without deleting your existing data! + +Pull in the latest image from docker. Supports both `amd64` and `arm64` CPU architectures. + +```shell +docker pull mintplexlabs/anythingllm +``` + + + + + + + + + + + + + + + + + +
Mount the storage locally and run AnythingLLM in Docker
+ Linux/MacOs + + +```shell +export STORAGE_LOCATION=$HOME/anythingllm && \ +mkdir -p $STORAGE_LOCATION && \ +touch "$STORAGE_LOCATION/.env" && \ +docker run -d -p 3001:3001 \ +--cap-add SYS_ADMIN \ +-v ${STORAGE_LOCATION}:/app/server/storage \ +-v ${STORAGE_LOCATION}/.env:/app/server/.env \ +-e STORAGE_DIR="/app/server/storage" \ +mintplexlabs/anythingllm +``` + +
+ Windows + + +```powershell +# Run this in powershell terminal +$env:STORAGE_LOCATION="$HOME\Documents\anythingllm"; ` +If(!(Test-Path $env:STORAGE_LOCATION)) {New-Item $env:STORAGE_LOCATION -ItemType Directory}; ` +If(!(Test-Path "$env:STORAGE_LOCATION\.env")) {New-Item "$env:STORAGE_LOCATION\.env" -ItemType File}; ` +docker run -d -p 3001:3001 ` +--cap-add SYS_ADMIN ` +-v "$env:STORAGE_LOCATION`:/app/server/storage" ` +-v "$env:STORAGE_LOCATION\.env:/app/server/.env" ` +-e STORAGE_DIR="/app/server/storage" ` +mintplexlabs/anythingllm; +``` + +
Docker Compose + + +```yaml +version: '3.8' +services: + anythingllm: + image: mintplexlabs/anythingllm + container_name: anythingllm + ports: + - "3001:3001" + cap_add: + - SYS_ADMIN + environment: + # Adjust for your environment + - STORAGE_DIR=/app/server/storage + - JWT_SECRET="make this a large list of random numbers and letters 20+" + - LLM_PROVIDER=ollama + - OLLAMA_BASE_PATH=http://127.0.0.1:11434 + - OLLAMA_MODEL_PREF=llama2 + - OLLAMA_MODEL_TOKEN_LIMIT=4096 + - EMBEDDING_ENGINE=ollama + - EMBEDDING_BASE_PATH=http://127.0.0.1:11434 + - EMBEDDING_MODEL_PREF=nomic-embed-text:latest + - EMBEDDING_MODEL_MAX_CHUNK_LENGTH=8192 + - VECTOR_DB=lancedb + - WHISPER_PROVIDER=local + - TTS_PROVIDER=native + - PASSWORDMINCHAR=8 + # Add any other keys here for services or settings + # you can find in the docker/.env.example file + volumes: + - anythingllm_storage:/app/server/storage + restart: always + +volumes: + anythingllm_storage: + driver: local + driver_opts: + type: none + o: bind + device: /path/on/local/disk +``` + +
+ +Go to `http://localhost:3001` and you are now using AnythingLLM! All your data and progress will persist between +container rebuilds or pulls from Docker Hub. + +## How to use the user interface + +- To access the full application, visit `http://localhost:3001` in your browser. + +## About UID and GID in the ENV + +- The UID and GID are set to 1000 by default. This is the default user in the Docker container and on most host operating systems. If there is a mismatch between your host user UID and GID and what is set in the `.env` file, you may experience permission issues. + +## Build locally from source _not recommended for casual use_ + +- `git clone` this repo and `cd anything-llm` to get to the root directory. +- `touch server/storage/anythingllm.db` to create empty SQLite DB file. +- `cd docker/` +- `cp .env.example .env` **you must do this before building** +- `docker-compose up -d --build` to build the image - this will take a few moments. + +Your docker host will show the image as online once the build process is completed. This will build the app to `http://localhost:3001`. + +## Integrations and one-click setups + +The integrations below are templates or tooling built by the community to make running the docker experience of AnythingLLM easier. + +### Use the Midori AI Subsystem to Manage AnythingLLM + +Follow the setup found on [Midori AI Subsystem Site](https://io.midori-ai.xyz/subsystem/manager/) for your host OS +After setting that up install the AnythingLLM docker backend to the Midori AI Subsystem. + +Once that is done, you are all set! + +## Common questions and fixes + +### Cannot connect to service running on localhost! + +If you are in docker and cannot connect to a service running on your host machine running on a local interface or loopback: + +- `localhost` +- `127.0.0.1` +- `0.0.0.0` + +> [!IMPORTANT] +> On linux `http://host.docker.internal:xxxx` does not work. +> Use `http://172.17.0.1:xxxx` instead to emulate this functionality. + +Then in docker you need to replace that localhost part with `host.docker.internal`. For example, if running Ollama on the host machine, bound to http://127.0.0.1:11434 you should put `http://host.docker.internal:11434` into the connection URL in AnythingLLM. + + +### API is not working, cannot login, LLM is "offline"? + +You are likely running the docker container on a remote machine like EC2 or some other instance where the reachable URL +is not `http://localhost:3001` and instead is something like `http://193.xx.xx.xx:3001` - in this case all you need to do is add the following to your `frontend/.env.production` before running `docker-compose up -d --build` + +``` +# frontend/.env.production +GENERATE_SOURCEMAP=false +VITE_API_BASE="http://:3001/api" +``` + +For example, if the docker instance is available on `192.186.1.222` your `VITE_API_BASE` would look like `VITE_API_BASE="http://192.186.1.222:3001/api"` in `frontend/.env.production`. + +### Having issues with Ollama? + +If you are getting errors like `llama:streaming - could not stream chat. Error: connect ECONNREFUSED 172.17.0.1:11434` then visit the README below. + +[Fix common issues with Ollama](../server/utils/AiProviders/ollama/README.md) + +### Still not working? + +[Ask for help on Discord](https://discord.gg/6UyHPeGZAC) diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml new file mode 100644 index 0000000000000000000000000000000000000000..b5782ee717f4cd7b81e4d5ca71afecc08f2a4e08 --- /dev/null +++ b/docker/docker-compose.yml @@ -0,0 +1,31 @@ +name: anythingllm + +networks: + anything-llm: + driver: bridge + +services: + anything-llm: + container_name: anythingllm + build: + context: ../. + dockerfile: ./docker/Dockerfile + args: + ARG_UID: ${UID:-1000} + ARG_GID: ${GID:-1000} + cap_add: + - SYS_ADMIN + volumes: + - "./.env:/app/server/.env" + - "../server/storage:/app/server/storage" + - "../collector/hotdir/:/app/collector/hotdir" + - "../collector/outputs/:/app/collector/outputs" + user: "${UID:-1000}:${GID:-1000}" + ports: + - "3001:3001" + env_file: + - .env + networks: + - anything-llm + extra_hosts: + - "host.docker.internal:host-gateway" diff --git a/docker/docker-entrypoint.sh b/docker/docker-entrypoint.sh new file mode 100644 index 0000000000000000000000000000000000000000..80296accc2fc7f4a95688c3cc3b22fe5c920f9a4 --- /dev/null +++ b/docker/docker-entrypoint.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +# Check if STORAGE_DIR is set +if [ -z "$STORAGE_DIR" ]; then + echo "================================================================" + echo "⚠️ ⚠️ ⚠️ WARNING: STORAGE_DIR environment variable is not set! ⚠️ ⚠️ ⚠️" + echo "" + echo "Not setting this will result in data loss on container restart since" + echo "the application will not have a persistent storage location." + echo "It can also result in weird errors in various parts of the application." + echo "" + echo "Please run the container with the official docker command at" + echo "https://docs.anythingllm.com/installation-docker/quickstart" + echo "" + echo "⚠️ ⚠️ ⚠️ WARNING: STORAGE_DIR environment variable is not set! ⚠️ ⚠️ ⚠️" + echo "================================================================" +fi + +{ + cd /app/server/ && + npx prisma generate --schema=./prisma/schema.prisma && + npx prisma migrate deploy --schema=./prisma/schema.prisma && + node /app/server/index.js +} & +{ node /app/collector/index.js; } & +wait -n +exit $? \ No newline at end of file diff --git a/docker/docker-healthcheck.sh b/docker/docker-healthcheck.sh new file mode 100644 index 0000000000000000000000000000000000000000..49bee3e1bf0e090754226ffd7baf2f5c10e5eb4f --- /dev/null +++ b/docker/docker-healthcheck.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +# Send a request to the specified URL +response=$(curl --write-out '%{http_code}' --silent --output /dev/null http://localhost:3001/api/ping) + +# If the HTTP response code is 200 (OK), the server is up +if [ "$response" -eq 200 ]; then + echo "Server is up" + exit 0 +else + echo "Server is down" + exit 1 +fi diff --git a/docker/vex/CVE-2019-10790.vex.json b/docker/vex/CVE-2019-10790.vex.json new file mode 100644 index 0000000000000000000000000000000000000000..4233fd146d497fb7cbd398217f0857178e3a958c --- /dev/null +++ b/docker/vex/CVE-2019-10790.vex.json @@ -0,0 +1,22 @@ +{ + "@context": "https://openvex.dev/ns/v0.2.0", + "@id": "https://openvex.dev/docs/public/vex-6750d79bb005487e11d10f81d0b3ac92c47e6e259292c6b2d02558f9f4bca52d", + "author": "tim@mintplexlabs.com", + "timestamp": "2024-07-22T13:49:12.883675-07:00", + "version": 1, + "statements": [ + { + "vulnerability": { + "name": "CVE-2019-10790" + }, + "timestamp": "2024-07-22T13:49:12.883678-07:00", + "products": [ + { + "@id": "pkg:npm/taffydb@2.6.2" + } + ], + "status": "not_affected", + "justification": "vulnerable_code_not_in_execute_path" + } + ] +} \ No newline at end of file diff --git a/docker/vex/CVE-2024-29415.vex.json b/docker/vex/CVE-2024-29415.vex.json new file mode 100644 index 0000000000000000000000000000000000000000..dfe5b4623a115e5e924dbee11aedb72e89548ae2 --- /dev/null +++ b/docker/vex/CVE-2024-29415.vex.json @@ -0,0 +1,22 @@ +{ + "@context": "https://openvex.dev/ns/v0.2.0", + "@id": "https://openvex.dev/docs/public/vex-939548c125c5bfebd3fd91e64c1c53bffacbde06b3611b4474ea90fa58045004", + "author": "tim@mintplexlabs.com", + "timestamp": "2024-07-19T16:08:47.147169-07:00", + "version": 1, + "statements": [ + { + "vulnerability": { + "name": "CVE-2024-29415" + }, + "timestamp": "2024-07-19T16:08:47.147172-07:00", + "products": [ + { + "@id": "pkg:npm/ip@2.0.0" + } + ], + "status": "not_affected", + "justification": "vulnerable_code_not_present" + } + ] +} \ No newline at end of file diff --git a/docker/vex/CVE-2024-37890.vex.json b/docker/vex/CVE-2024-37890.vex.json new file mode 100644 index 0000000000000000000000000000000000000000..13498ec66e028ca8870b16b1052ebfeecdf72249 --- /dev/null +++ b/docker/vex/CVE-2024-37890.vex.json @@ -0,0 +1,22 @@ +{ + "@context": "https://openvex.dev/ns/v0.2.0", + "@id": "https://openvex.dev/docs/public/vex-939548c125c5bfebd3fd91e64c1c53bffacbde06b3611b4474ea90fa58045004", + "author": "tim@mintplexlabs.com", + "timestamp": "2024-07-19T16:08:47.147169-07:00", + "version": 1, + "statements": [ + { + "vulnerability": { + "name": "CVE-2024-37890" + }, + "timestamp": "2024-07-19T16:08:47.147172-07:00", + "products": [ + { + "@id": "pkg:npm/ws@8.14.2" + } + ], + "status": "not_affected", + "justification": "vulnerable_code_not_in_execute_path" + } + ] +} \ No newline at end of file diff --git a/docker/vex/CVE-2024-4068.vex.json b/docker/vex/CVE-2024-4068.vex.json new file mode 100644 index 0000000000000000000000000000000000000000..41f73ed3e60b4a3f9c2c96497075f91c453c1121 --- /dev/null +++ b/docker/vex/CVE-2024-4068.vex.json @@ -0,0 +1,22 @@ +{ + "@context": "https://openvex.dev/ns/v0.2.0", + "@id": "https://openvex.dev/docs/public/vex-939548c125c5bfebd3fd91e64c1c53bffacbde06b3611b4474ea90fa58045004", + "author": "tim@mintplexlabs.com", + "timestamp": "2024-07-19T16:08:47.147169-07:00", + "version": 1, + "statements": [ + { + "vulnerability": { + "name": "CVE-2024-4068" + }, + "timestamp": "2024-07-19T16:08:47.147172-07:00", + "products": [ + { + "@id": "pkg:npm/braces@3.0.2" + } + ], + "status": "not_affected", + "justification": "vulnerable_code_not_present" + } + ] +} \ No newline at end of file diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000000000000000000000000000000000000..861ff6369cbb4ba3f3d9e6373e2fbd7f4ddebd3b --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,91 @@ +import globals from "./server/node_modules/globals/index.js" +import eslintRecommended from "./server/node_modules/@eslint/js/src/index.js" +import eslintConfigPrettier from "./server/node_modules/eslint-config-prettier/index.js" +import prettier from "./server/node_modules/eslint-plugin-prettier/eslint-plugin-prettier.js" +import react from "./server/node_modules/eslint-plugin-react/index.js" +import reactRefresh from "./server/node_modules/eslint-plugin-react-refresh/index.js" +import reactHooks from "./server/node_modules/eslint-plugin-react-hooks/index.js" +import ftFlow from "./server/node_modules/eslint-plugin-ft-flow/dist/index.js" +import hermesParser from "./server/node_modules/hermes-eslint/dist/index.js" + +const reactRecommended = react.configs.recommended +const jsxRuntime = react.configs["jsx-runtime"] + +export default [ + eslintRecommended.configs.recommended, + eslintConfigPrettier, + { + ignores: ["**/*.test.js"], + languageOptions: { + parser: hermesParser, + parserOptions: { + ecmaFeatures: { jsx: true } + }, + ecmaVersion: 2020, + sourceType: "module", + globals: { + ...globals.browser, + ...globals.es2020, + ...globals.node + } + }, + linterOptions: { reportUnusedDisableDirectives: true }, + settings: { react: { version: "18.2" } }, + plugins: { + ftFlow, + react, + "jsx-runtime": jsxRuntime, + "react-hooks": reactHooks, + prettier + }, + rules: { + ...reactRecommended.rules, + ...reactHooks.configs.recommended.rules, + ...ftFlow.recommended, + "no-unused-vars": "warn", + "no-undef": "warn", + "no-empty": "warn", + "no-extra-boolean-cast": "warn", + "no-prototype-builtins": "off", + "prettier/prettier": "warn" + } + }, + { + files: ["frontend/src/**/*.js"], + plugins: { + ftFlow, + prettier + }, + rules: { + "prettier/prettier": "warn" + } + }, + { + files: [ + "server/endpoints/**/*.js", + "server/models/**/*.js", + "server/swagger/**/*.js", + "server/utils/**/*.js", + "server/index.js" + ], + rules: { + "no-undef": "warn" + } + }, + { + files: ["frontend/src/**/*.jsx"], + plugins: { + ftFlow, + react, + "jsx-runtime": jsxRuntime, + "react-hooks": reactHooks, + "react-refresh": reactRefresh, + prettier + }, + rules: { + ...jsxRuntime.rules, + "react/prop-types": "off", // FIXME + "react-refresh/only-export-components": "warn" + } + } +] diff --git a/extras/scripts/verifyPackageVersions.mjs b/extras/scripts/verifyPackageVersions.mjs new file mode 100644 index 0000000000000000000000000000000000000000..fad015aaad64b98ee738485ae2085dab2293823f --- /dev/null +++ b/extras/scripts/verifyPackageVersions.mjs @@ -0,0 +1,34 @@ +import serverPackageJson from '../../server/package.json' assert { type: 'json' }; +import collectorPackageJson from '../../collector/package.json' assert { type: 'json' }; +const { dependencies: serverDependencies } = serverPackageJson; +const { dependencies: collectorDependencies } = collectorPackageJson; + +const serverDependenciesKeys = Object.keys(serverDependencies); +const collectorDependenciesKeys = Object.keys(collectorDependencies); +const commonDependencies = Array.from(new Set([ + ...serverDependenciesKeys.filter((key) => collectorDependenciesKeys.includes(key)), + ...collectorDependenciesKeys.filter((key) => serverDependenciesKeys.includes(key)), +])); + +const ignores = [ + "@langchain/community" // We are slowly removing this dependency from the app - its use is not critical +] + +console.log(`${commonDependencies.length} common dependencies found`, commonDependencies); +console.log(`Verifying (serverVersion == collectorVersion) for each common dependency`); + +const failed = []; +commonDependencies.forEach((dependency) => { + console.log(`Verifying ${dependency}: ${serverDependencies[dependency]} == ${collectorDependencies[dependency]}`); + if (serverDependencies[dependency] !== collectorDependencies[dependency]) { + if (ignores.includes(dependency)) console.log(`${dependency} is in ignore list.`); + else failed.push({ dependency, serverVersion: serverDependencies[dependency], collectorVersion: collectorDependencies[dependency] }); + } +}); + +if (failed.length > 0) { + console.log(`❌ ${failed.length} dependencies failed to verify`, JSON.stringify(failed, null, 2)); + throw new Error(`${failed.length} dependencies failed to verify!`); +} + +console.log(`👍 All dependencies match between server and collector!`); diff --git a/extras/support/announcements/2025-04-08.json b/extras/support/announcements/2025-04-08.json new file mode 100644 index 0000000000000000000000000000000000000000..58535ecc6098f2e83c98181bee0522728363d3f2 --- /dev/null +++ b/extras/support/announcements/2025-04-08.json @@ -0,0 +1,26 @@ +[ + { + "thumbnail_url": "https://cdn.anythingllm.com/support/announcements/assets/mcp.jpg", + "title": "MCP Support", + "short_description": "Import and leverage MCP tools using AnythingLLM.", + "goto": "https://docs.anythingllm.com/mcp-compatibility/overview", + "author": "AnythingLLM", + "date": "April 8, 2025" + }, + { + "thumbnail_url": "https://blogs.nvidia.com/wp-content/uploads/2025/03/nv-raig-032525-nv-blog-1280x680-1-scaled.jpg", + "title": "NVIDIA NIM Support", + "short_description": "Unlock the power of NVIDIA NIM on Windows with RTX GPU in our latest update via the NVIDIA NIM LLM provider.", + "goto": "https://blogs.nvidia.com/blog/rtx-ai-garage-nim-blueprints-g-assist", + "author": "NVIDIA", + "date": "March 25, 2025" + }, + { + "thumbnail_url": null, + "title": "Community Hub Updates", + "short_description": "We refreshed the Community Hub with a new look and feel. Check it out!", + "goto": "https://hub.anythingllm.com", + "author": "AnythingLLM", + "date": "March 12, 2025" + } +] \ No newline at end of file diff --git a/extras/support/announcements/2025-07-08.json b/extras/support/announcements/2025-07-08.json new file mode 100644 index 0000000000000000000000000000000000000000..2fb306e88bb4380dddd242f1d421c21d42b01097 --- /dev/null +++ b/extras/support/announcements/2025-07-08.json @@ -0,0 +1,25 @@ +[ + { + "thumbnail_url": "https://cdn.anythingllm.com/support/announcements/assets/private-browsing.png", + "title": "Private Web Scraping", + "short_description": "Scrape private, gated, or authenticated websites using the browser tool.", + "goto": "https://docs.anythingllm.com/features/browser-tool", + "author": "AnythingLLM", + "date": "July 8, 2025" + }, + { + "thumbnail_url": "https://cdn.anythingllm.com/support/announcements/assets/mobile.png", + "title": "AnythingLLM Mobile Beta", + "short_description": "AnythingLLM on-device, offline, and private. Syncs with AnythingLLM.", + "goto": "https://docs.google.com/forms/d/e/1FAIpQLSdrMRCUXVDWKrtNTcHzVcHQk_SRoiT8X8tiawTFtAhjMq_L6Q/viewform", + "author": "AnythingLLM", + "date": "July 3, 2025" + }, + { + "title": "Community Hub updates", + "short_description": "You can now easily push and pull Agent Flows, System Prompts, and more to the AnythingLLM Community Hub.", + "goto": "https://hub.anythingllm.com", + "author": "AnythingLLM", + "date": "June 25, 2025" + } +] \ No newline at end of file diff --git a/extras/support/announcements/assets/mcp.jpg b/extras/support/announcements/assets/mcp.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b0abd8a9cfd9b23e132f69bda1e2a485ab000f97 Binary files /dev/null and b/extras/support/announcements/assets/mcp.jpg differ diff --git a/extras/support/announcements/assets/mobile.png b/extras/support/announcements/assets/mobile.png new file mode 100644 index 0000000000000000000000000000000000000000..b0b2a24532f123a333417817432a733d50cfd75d --- /dev/null +++ b/extras/support/announcements/assets/mobile.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:531f0c9bbc815e1ce9eeebee66dfdf2ffdd5c2c9d3281928ee85f84425f15ef5 +size 61516 diff --git a/extras/support/announcements/assets/private-browsing.png b/extras/support/announcements/assets/private-browsing.png new file mode 100644 index 0000000000000000000000000000000000000000..534812e3dabdf89b883afe78416b7cb8cd4d6282 --- /dev/null +++ b/extras/support/announcements/assets/private-browsing.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e7b5054bf4ee1af2982bbaded12da87ac3f17ade5a34099673bf62f28d3e247f +size 46076 diff --git a/extras/support/announcements/list.txt b/extras/support/announcements/list.txt new file mode 100644 index 0000000000000000000000000000000000000000..8ca271444e8ff060eaf20b173683ba5f10142cf0 --- /dev/null +++ b/extras/support/announcements/list.txt @@ -0,0 +1,2 @@ +2025-07-08.json +2025-04-08.json \ No newline at end of file diff --git a/frontend/.env.example b/frontend/.env.example new file mode 100644 index 0000000000000000000000000000000000000000..05619d24f67b702e61dc86306dfcdeb3802b9e94 --- /dev/null +++ b/frontend/.env.example @@ -0,0 +1,3 @@ +VITE_API_BASE='http://localhost:3001/api' # Use this URL when developing locally +# VITE_API_BASE="https://$CODESPACE_NAME-3001.$GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN/api" # for GitHub Codespaces +# VITE_API_BASE='/api' # Use this URL deploying on non-localhost address OR in docker. diff --git a/frontend/.gitignore b/frontend/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..77e294d036e8f9ef7954c92d2b3da4936698c0f5 --- /dev/null +++ b/frontend/.gitignore @@ -0,0 +1,27 @@ +# 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? +bundleinspector.html +.env.production +flow-typed diff --git a/frontend/.nvmrc b/frontend/.nvmrc new file mode 100644 index 0000000000000000000000000000000000000000..59f4a2f3ab843c5f1b4767ef0eae1d72a7597393 --- /dev/null +++ b/frontend/.nvmrc @@ -0,0 +1 @@ +v18.13.0 \ No newline at end of file diff --git a/frontend/index.html b/frontend/index.html new file mode 100644 index 0000000000000000000000000000000000000000..22cc5b0f627d0d364b6dbdd9c43defb4f6503ca3 --- /dev/null +++ b/frontend/index.html @@ -0,0 +1,38 @@ + + + + + + + + AnythingLLM | Your personal LLM trained on anything + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/frontend/jsconfig.json b/frontend/jsconfig.json new file mode 100644 index 0000000000000000000000000000000000000000..4cc5167064f05131fa2514a4f4f2c94410b29947 --- /dev/null +++ b/frontend/jsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "esnext", + "jsx": "react", + "paths": { + "@/*": [ + "./src/*" + ] + } + } +} \ No newline at end of file diff --git a/frontend/package.json b/frontend/package.json new file mode 100644 index 0000000000000000000000000000000000000000..dab34cc4e8c2c7b03fe1993c76a628d184521738 --- /dev/null +++ b/frontend/package.json @@ -0,0 +1,78 @@ +{ + "name": "anything-llm-frontend", + "private": false, + "license": "MIT", + "type": "module", + "scripts": { + "start": "vite --open", + "dev": "cross-env NODE_ENV=development vite --debug --host=0.0.0.0", + "build": "vite build && node scripts/postbuild.js", + "lint": "yarn prettier --ignore-path ../.prettierignore --write ./src", + "preview": "vite preview" + }, + "dependencies": { + "@microsoft/fetch-event-source": "^2.0.1", + "@mintplex-labs/piper-tts-web": "^1.0.4", + "@phosphor-icons/react": "^2.1.7", + "@tremor/react": "^3.15.1", + "dompurify": "^3.0.8", + "file-saver": "^2.0.5", + "he": "^1.2.0", + "highlight.js": "^11.9.0", + "i18next": "^23.11.3", + "i18next-browser-languagedetector": "^7.2.1", + "js-levenshtein": "^1.1.6", + "katex": "^0.6.0", + "lodash.debounce": "^4.0.8", + "markdown-it": "^13.0.1", + "moment": "^2.30.1", + "onnxruntime-web": "^1.18.0", + "pluralize": "^8.0.0", + "qrcode.react": "^4.2.0", + "react": "^18.2.0", + "react-beautiful-dnd": "13.1.1", + "react-confetti-explosion": "^2.1.2", + "react-device-detect": "^2.2.2", + "react-dom": "^18.2.0", + "react-dropzone": "^14.2.3", + "react-highlight-words": "^0.21.0", + "react-i18next": "^14.1.1", + "react-loading-skeleton": "^3.1.0", + "react-router-dom": "^6.3.0", + "react-speech-recognition": "^3.10.0", + "react-tag-input-component": "^2.0.2", + "react-toastify": "^9.1.3", + "react-tooltip": "^5.25.2", + "recharts": "^2.12.5", + "recharts-to-png": "^2.3.1", + "text-case": "^1.0.9", + "truncate": "^3.0.0", + "uuid": "^9.0.0" + }, + "devDependencies": { + "@esbuild-plugins/node-globals-polyfill": "^0.1.1", + "@types/react": "^18.2.23", + "@types/react-dom": "^18.2.8", + "@types/react-router-dom": "^5.3.3", + "@vitejs/plugin-react": "^4.0.0-beta.0", + "autoprefixer": "^10.4.14", + "buffer": "^6.0.3", + "cross-env": "^7.0.3", + "eslint": "^8.50.0", + "eslint-config-prettier": "^9.0.0", + "eslint-plugin-ft-flow": "^3.0.0", + "eslint-plugin-prettier": "^5.0.0", + "eslint-plugin-react": "^7.33.2", + "eslint-plugin-react-hooks": "^4.6.0", + "eslint-plugin-react-refresh": "^0.4.3", + "flow-bin": "^0.217.0", + "flow-remove-types": "^2.217.1", + "globals": "^13.21.0", + "hermes-eslint": "^0.15.0", + "postcss": "^8.4.23", + "prettier": "^3.0.3", + "rollup-plugin-visualizer": "^5.9.0", + "tailwindcss": "^3.3.1", + "vite": "^4.3.0" + } +} \ No newline at end of file diff --git a/frontend/postcss.config.js b/frontend/postcss.config.js new file mode 100644 index 0000000000000000000000000000000000000000..869bdc11df8aa4c8c14549fa77c82b4a0a76386c --- /dev/null +++ b/frontend/postcss.config.js @@ -0,0 +1,7 @@ +import tailwind from 'tailwindcss' +import autoprefixer from 'autoprefixer' +import tailwindConfig from './tailwind.config.js' + +export default { + plugins: [tailwind(tailwindConfig), autoprefixer], +} \ No newline at end of file diff --git a/frontend/public/anything-llm-dark.png b/frontend/public/anything-llm-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..a8dc0b35d23c9c39937b221582079cb4653e7804 --- /dev/null +++ b/frontend/public/anything-llm-dark.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:57e0f710352bb127b5c0c452065e6f2c41303462252047d51e4825a6533d87f3 +size 8413 diff --git a/frontend/public/anything-llm-light.png b/frontend/public/anything-llm-light.png new file mode 100644 index 0000000000000000000000000000000000000000..5788ad63fe80b8a914097d1fe5a9d659be12e647 --- /dev/null +++ b/frontend/public/anything-llm-light.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:67ade0a8602acac0e32cf167d68689bf38523ffd484346e12fcfdf9e7e59b93f +size 6324 diff --git a/frontend/public/embed/anythingllm-chat-widget.min.css b/frontend/public/embed/anythingllm-chat-widget.min.css new file mode 100644 index 0000000000000000000000000000000000000000..cce063d48ac072734738646f8c89b28b7e3b47bb --- /dev/null +++ b/frontend/public/embed/anythingllm-chat-widget.min.css @@ -0,0 +1 @@ +*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgb(59 130 246 / .5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgb(59 130 246 / .5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.allm-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.allm-fixed{position:fixed}.allm-absolute{position:absolute}.allm-relative{position:relative}.allm-sticky{position:sticky}.allm-inset-0{top:0;right:0;bottom:0;left:0}.allm-bottom-0{bottom:0}.allm-bottom-\[10rem\]{bottom:10rem}.allm-left-0{left:0}.allm-right-0{right:0}.allm-right-\[46px\]{right:46px}.allm-right-\[50px\]{right:50px}.allm-top-0{top:0}.allm-top-\[64px\]{top:64px}.allm-z-10{z-index:10}.allm-z-50{z-index:50}.allm-m-0{margin:0}.allm-mx-2{margin-left:.5rem;margin-right:.5rem}.allm-mx-4{margin-left:1rem;margin-right:1rem}.allm-mx-\[20px\]{margin-left:20px;margin-right:20px}.allm-my-1{margin-top:.25rem;margin-bottom:.25rem}.allm-my-3{margin-top:.75rem;margin-bottom:.75rem}.-allm-mt-10{margin-top:-2.5rem}.allm-mb-1{margin-bottom:.25rem}.allm-mb-2{margin-bottom:.5rem}.allm-mb-3{margin-bottom:.75rem}.allm-mb-4{margin-bottom:1rem}.allm-mb-8{margin-bottom:2rem}.allm-ml-2{margin-left:.5rem}.allm-ml-4{margin-left:1rem}.allm-ml-\[54px\]{margin-left:54px}.allm-ml-\[9px\]{margin-left:9px}.allm-mr-4{margin-right:1rem}.allm-mr-6{margin-right:1.5rem}.allm-mr-\[37px\]{margin-right:37px}.allm-mt-2{margin-top:.5rem}.allm-mt-3{margin-top:.75rem}.allm-mt-4{margin-top:1rem}.allm-mt-auto{margin-top:auto}.allm-block{display:block}.allm-inline-block{display:inline-block}.allm-flex{display:flex}.allm-inline-flex{display:inline-flex}.allm-hidden{display:none}.allm-h-3{height:.75rem}.allm-h-4{height:1rem}.allm-h-8{height:2rem}.allm-h-9{height:2.25rem}.allm-h-\[22px\]{height:22px}.allm-h-\[76px\]{height:76px}.allm-h-fit{height:-moz-fit-content;height:fit-content}.allm-h-full{height:100%}.allm-max-h-\[100px\]{max-height:100px}.allm-max-h-\[82vh\]{max-height:82vh}.allm-min-h-0{min-height:0}.allm-w-3{width:.75rem}.allm-w-4{width:1rem}.allm-w-8{width:2rem}.allm-w-9{width:2.25rem}.allm-w-\[75\%\]{width:75%}.allm-w-full{width:100%}.allm-min-w-\[52px\]{min-width:52px}.allm-max-w-full{max-width:100%}.allm-flex-1{flex:1 1 0%}.allm-flex-shrink-0{flex-shrink:0}.allm-flex-grow{flex-grow:1}.allm-rotate-180{--tw-rotate:180deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes allm-pulse{50%{opacity:.5}}.allm-animate-pulse{animation:allm-pulse 2s cubic-bezier(.4,0,.6,1) infinite}@keyframes allm-spin{to{transform:rotate(360deg)}}.allm-animate-spin{animation:allm-spin 1s linear infinite}.allm-cursor-pointer{cursor:pointer}.allm-cursor-text{cursor:text}.allm-resize-none{resize:none}.allm-flex-col{flex-direction:column}.allm-items-start{align-items:flex-start}.allm-items-center{align-items:center}.allm-justify-start{justify-content:flex-start}.allm-justify-end{justify-content:flex-end}.allm-justify-center{justify-content:center}.allm-justify-between{justify-content:space-between}.allm-gap-x-1{-moz-column-gap:.25rem;column-gap:.25rem}.allm-gap-x-1\.5{-moz-column-gap:.375rem;column-gap:.375rem}.allm-gap-x-2{-moz-column-gap:.5rem;column-gap:.5rem}.allm-gap-x-4{-moz-column-gap:1rem;column-gap:1rem}.allm-gap-x-5{-moz-column-gap:1.25rem;column-gap:1.25rem}.allm-gap-x-\[12px\]{-moz-column-gap:12px;column-gap:12px}.allm-gap-y-1{row-gap:.25rem}.allm-gap-y-2{row-gap:.5rem}.allm-gap-y-4{row-gap:1rem}.allm-overflow-hidden{overflow:hidden}.allm-overflow-x-auto{overflow-x:auto}.allm-overflow-y-auto{overflow-y:auto}.allm-overflow-y-scroll{overflow-y:scroll}.allm-whitespace-pre-line{white-space:pre-line}.allm-whitespace-pre-wrap{white-space:pre-wrap}.allm-break-words{overflow-wrap:break-word}.allm-rounded{border-radius:.25rem}.allm-rounded-2xl{border-radius:1rem}.allm-rounded-full{border-radius:9999px}.allm-rounded-lg{border-radius:.5rem}.allm-rounded-sm{border-radius:.125rem}.allm-rounded-xl{border-radius:.75rem}.allm-rounded-t-2xl{border-top-left-radius:1rem;border-top-right-radius:1rem}.allm-rounded-t-\[18px\]{border-top-left-radius:18px;border-top-right-radius:18px}.allm-rounded-t-lg{border-top-left-radius:.5rem;border-top-right-radius:.5rem}.allm-rounded-bl-\[18px\]{border-bottom-left-radius:18px}.allm-rounded-bl-\[4px\]{border-bottom-left-radius:4px}.allm-rounded-br-\[18px\]{border-bottom-right-radius:18px}.allm-rounded-br-\[4px\]{border-bottom-right-radius:4px}.allm-border{border-width:1px}.allm-border-l-2{border-left-width:2px}.allm-border-none{border-style:none}.allm-border-gray-200{--tw-border-opacity:1;border-color:rgb(229 231 235 / var(--tw-border-opacity))}.allm-border-gray-300{--tw-border-opacity:1;border-color:rgb(209 213 219 / var(--tw-border-opacity))}.allm-border-red-500{--tw-border-opacity:1;border-color:rgb(239 68 68 / var(--tw-border-opacity))}.allm-border-white\/10{border-color:#ffffff1a}.allm-bg-\[\#1e1e1e\]{--tw-bg-opacity:1;background-color:rgb(30 30 30 / var(--tw-bg-opacity))}.allm-bg-\[\#2d2d2d\]{--tw-bg-opacity:1;background-color:rgb(45 45 45 / var(--tw-bg-opacity))}.allm-bg-\[\#ffffff14\]{background-color:#ffffff14}.allm-bg-black\/20{background-color:#0003}.allm-bg-gray-100{--tw-bg-opacity:1;background-color:rgb(243 244 246 / var(--tw-bg-opacity))}.allm-bg-red-200{--tw-bg-opacity:1;background-color:rgb(254 202 202 / var(--tw-bg-opacity))}.allm-bg-red-300{--tw-bg-opacity:1;background-color:rgb(252 165 165 / var(--tw-bg-opacity))}.allm-bg-red-50{--tw-bg-opacity:1;background-color:rgb(254 242 242 / var(--tw-bg-opacity))}.allm-bg-transparent{background-color:transparent}.allm-bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255 / var(--tw-bg-opacity))}.allm-p-2{padding:.5rem}.allm-p-4{padding:1rem}.allm-px-0{padding-left:0;padding-right:0}.allm-px-1{padding-left:.25rem;padding-right:.25rem}.allm-px-1\.5{padding-left:.375rem;padding-right:.375rem}.allm-px-2{padding-left:.5rem;padding-right:.5rem}.allm-px-4{padding-left:1rem;padding-right:1rem}.allm-px-\[22px\]{padding-left:22px;padding-right:22px}.allm-py-1{padding-top:.25rem;padding-bottom:.25rem}.allm-py-2{padding-top:.5rem;padding-bottom:.5rem}.allm-py-4{padding-top:1rem;padding-bottom:1rem}.allm-py-\[11px\]{padding-top:11px;padding-bottom:11px}.allm-py-\[5px\]{padding-top:5px;padding-bottom:5px}.allm-pb-2{padding-bottom:.5rem}.allm-pb-4{padding-bottom:1rem}.allm-pb-8{padding-bottom:2rem}.allm-pb-\[100px\]{padding-bottom:100px}.allm-pl-0{padding-left:0}.allm-pl-2{padding-left:.5rem}.allm-pt-4{padding-top:1rem}.allm-pt-\[5px\]{padding-top:5px}.allm-text-left{text-align:left}.allm-text-center{text-align:center}.allm-text-right{text-align:right}.allm-font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.allm-font-sans{font-family:plus-jakarta-sans,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji"}.\!allm-text-xs{font-size:.75rem!important;line-height:1rem!important}.allm-text-2xl{font-size:1.5rem;line-height:2rem}.allm-text-\[10px\]{font-size:10px}.allm-text-\[14px\]{font-size:14px}.allm-text-base{font-size:1rem;line-height:1.5rem}.allm-text-sm{font-size:.875rem;line-height:1.25rem}.allm-text-xs{font-size:.75rem;line-height:1rem}.allm-font-bold{font-weight:700}.allm-font-medium{font-weight:500}.allm-font-normal{font-weight:400}.allm-leading-\[20px\]{line-height:20px}.allm-text-\[\#22262899\]\/60{color:#22262899}.allm-text-\[\#222628\]{--tw-text-opacity:1;color:rgb(34 38 40 / var(--tw-text-opacity))}.allm-text-\[\#7A7D7E\]{--tw-text-opacity:1;color:rgb(122 125 126 / var(--tw-text-opacity))}.allm-text-\[\#858585\]{--tw-text-opacity:1;color:rgb(133 133 133 / var(--tw-text-opacity))}.allm-text-\[\#d4d4d4\]{--tw-text-opacity:1;color:rgb(212 212 212 / var(--tw-text-opacity))}.allm-text-black{--tw-text-opacity:1;color:rgb(0 0 0 / var(--tw-text-opacity))}.allm-text-gray-300{--tw-text-opacity:1;color:rgb(209 213 219 / var(--tw-text-opacity))}.allm-text-gray-400{--tw-text-opacity:1;color:rgb(156 163 175 / var(--tw-text-opacity))}.allm-text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128 / var(--tw-text-opacity))}.allm-text-gray-600{--tw-text-opacity:1;color:rgb(75 85 99 / var(--tw-text-opacity))}.allm-text-green-500{--tw-text-opacity:1;color:rgb(34 197 94 / var(--tw-text-opacity))}.allm-text-red-500{--tw-text-opacity:1;color:rgb(239 68 68 / var(--tw-text-opacity))}.allm-text-slate-400{--tw-text-opacity:1;color:rgb(148 163 184 / var(--tw-text-opacity))}.allm-text-slate-800\/60{color:#1e293b99}.allm-text-white{--tw-text-opacity:1;color:rgb(255 255 255 / var(--tw-text-opacity))}.allm-text-white\/50{color:#ffffff80}.allm-text-zinc-300{--tw-text-opacity:1;color:rgb(212 212 216 / var(--tw-text-opacity))}.allm-no-underline{text-decoration-line:none}.allm-shadow-\[0_4px_14px_rgba\(0\,0\,0\,0\.25\)\]{--tw-shadow:0 4px 14px rgba(0,0,0,.25);--tw-shadow-colored:0 4px 14px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.allm-shadow-lg{--tw-shadow:0 10px 15px -3px rgb(0 0 0 / .1),0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.allm-transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.allm-transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.msg-suggestion{animation-name:fadeIn;animation-duration:.3s;animation-timing-function:linear;animation-fill-mode:forwards}@keyframes fadeIn{0%{opacity:0%}25%{opacity:25%}50%{opacity:50%}75%{opacity:75%}to{opacity:100%}}.placeholder\:allm-text-slate-800\/60::-moz-placeholder{color:#1e293b99}.placeholder\:allm-text-slate-800\/60::placeholder{color:#1e293b99}.hover\:allm-cursor-pointer:hover{cursor:pointer}.hover\:allm-bg-\[\#ffffff20\]:hover{background-color:#ffffff20}.hover\:allm-bg-black\/50:hover{background-color:#00000080}.hover\:allm-bg-gray-100:hover{--tw-bg-opacity:1;background-color:rgb(243 244 246 / var(--tw-bg-opacity))}.hover\:allm-text-gray-500:hover{--tw-text-opacity:1;color:rgb(107 114 128 / var(--tw-text-opacity))}.hover\:allm-text-white:hover{--tw-text-opacity:1;color:rgb(255 255 255 / var(--tw-text-opacity))}.hover\:allm-underline:hover{text-decoration-line:underline}.hover\:allm-opacity-80:hover{opacity:.8}.hover\:allm-opacity-95:hover{opacity:.95}.hover\:allm-shadow-\[0_4px_14px_rgba\(0\,0\,0\,0\.5\)\]:hover{--tw-shadow:0 4px 14px rgba(0,0,0,.5);--tw-shadow-colored:0 4px 14px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.focus\:allm-outline-none:focus{outline:2px solid transparent;outline-offset:2px}.active\:allm-outline-none:active{outline:2px solid transparent;outline-offset:2px}.allm-group:hover .group-hover\:allm-text-\[\#22262899\]\/90{color:#222628e6} \ No newline at end of file diff --git a/frontend/public/embed/anythingllm-chat-widget.min.js b/frontend/public/embed/anythingllm-chat-widget.min.js new file mode 100644 index 0000000000000000000000000000000000000000..e416c36a9fb66791b6cb172ee98344790124e0f8 --- /dev/null +++ b/frontend/public/embed/anythingllm-chat-widget.min.js @@ -0,0 +1,37 @@ +!function(_t,xe){"object"==typeof exports&&typeof module<"u"?xe(exports):"function"==typeof define&&define.amd?define(["exports"],xe):xe((_t=typeof globalThis<"u"?globalThis:_t||self).EmbeddedAnythingLLM={})}(this,(function(_t){"use strict";var Hg,Vg,aN=Object.defineProperty,r1=(_t,xe,Ht)=>(((_t,xe,Ht)=>{xe in _t?aN(_t,xe,{enumerable:!0,configurable:!0,writable:!0,value:Ht}):_t[xe]=Ht})(_t,"symbol"!=typeof xe?xe+"":xe,Ht),Ht),xe=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function Ht(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var Cc={exports:{}},sa={},Sc={exports:{}},te={},Yr=Symbol.for("react.element"),a1=Symbol.for("react.portal"),s1=Symbol.for("react.fragment"),i1=Symbol.for("react.strict_mode"),l1=Symbol.for("react.profiler"),u1=Symbol.for("react.provider"),c1=Symbol.for("react.context"),d1=Symbol.for("react.forward_ref"),p1=Symbol.for("react.suspense"),f1=Symbol.for("react.memo"),m1=Symbol.for("react.lazy"),Nc=Symbol.iterator; +/** + * @license React + * react.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var Tc={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},wc=Object.assign,xc={};function ar(t,e,n){this.props=t,this.context=e,this.refs=xc,this.updater=n||Tc}function Rc(){}function ii(t,e,n){this.props=t,this.context=e,this.refs=xc,this.updater=n||Tc}ar.prototype.isReactComponent={},ar.prototype.setState=function(t,e){if("object"!=typeof t&&"function"!=typeof t&&null!=t)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,t,e,"setState")},ar.prototype.forceUpdate=function(t){this.updater.enqueueForceUpdate(this,t,"forceUpdate")},Rc.prototype=ar.prototype;var li=ii.prototype=new Rc;li.constructor=ii,wc(li,ar.prototype),li.isPureReactComponent=!0;var Lc=Array.isArray,Oc=Object.prototype.hasOwnProperty,ui={current:null},kc={key:!0,ref:!0,__self:!0,__source:!0};function Ic(t,e,n){var r,o={},a=null,s=null;if(null!=e)for(r in void 0!==e.ref&&(s=e.ref),void 0!==e.key&&(a=""+e.key),e)Oc.call(e,r)&&!kc.hasOwnProperty(r)&&(o[r]=e[r]);var i=arguments.length-2;if(1===i)o.children=n;else if(1>>1,$=S[k];if(!(0>>1;ko(pe,L))ue<$&&0>o(ce,pe)?(S[k]=ce,S[ue]=L,k=ue):(S[k]=pe,S[ge]=L,k=ge);else{if(!(ue<$&&0>o(ce,L)))break e;S[k]=ce,S[ue]=L,k=ue}}}return C}function o(S,C){var L=S.sortIndex-C.sortIndex;return 0!==L?L:S.id-C.id}if("object"==typeof performance&&"function"==typeof performance.now){var a=performance;t.unstable_now=function(){return a.now()}}else{var s=Date,i=s.now();t.unstable_now=function(){return s.now()-i}}var l=[],u=[],c=1,p=null,d=3,f=!1,b=!1,A=!1,y="function"==typeof setTimeout?setTimeout:null,h="function"==typeof clearTimeout?clearTimeout:null,g=typeof setImmediate<"u"?setImmediate:null;function E(S){for(var C=n(u);null!==C;){if(null===C.callback)r(u);else{if(!(C.startTime<=S))break;r(u),C.sortIndex=C.expirationTime,e(l,C)}C=n(u)}}function _(S){if(A=!1,E(S),!b)if(null!==n(l))b=!0,B(N);else{var C=n(u);null!==C&&x(_,C.startTime-S)}}function N(S,C){b=!1,A&&(A=!1,h(R),R=-1),f=!0;var L=d;try{for(E(C),p=n(l);null!==p&&(!(p.expirationTime>C)||S&&!W());){var k=p.callback;if("function"==typeof k){p.callback=null,d=p.priorityLevel;var $=k(p.expirationTime<=C);C=t.unstable_now(),"function"==typeof $?p.callback=$:p===n(l)&&r(l),E(C)}else r(l);p=n(l)}if(null!==p)var j=!0;else{var ge=n(u);null!==ge&&x(_,ge.startTime-C),j=!1}return j}finally{p=null,d=L,f=!1}}typeof navigator<"u"&&void 0!==navigator.scheduling&&void 0!==navigator.scheduling.isInputPending&&navigator.scheduling.isInputPending.bind(navigator.scheduling);var K,v=!1,T=null,R=-1,H=5,I=-1;function W(){return!(t.unstable_now()-IS||125k?(S.sortIndex=L,e(u,S),null===n(l)&&S===n(u)&&(A?(h(R),R=-1):A=!0,x(_,L-k))):(S.sortIndex=$,e(l,S),b||f||(b=!0,B(N))),S},t.unstable_shouldYield=W,t.unstable_wrapCallback=function(S){var C=d;return function(){var L=d;d=C;try{return S.apply(this,arguments)}finally{d=L}}}})(Uc),Pc.exports=Uc;var N1=Pc.exports,qc=U,dt=N1; +/** + * @license React + * react-dom.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */function M(t){for(var e="https://reactjs.org/docs/error-decoder.html?invariant="+t,n=1;n"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),fi=Object.prototype.hasOwnProperty,T1=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,Vc={},$c={};function Qe(t,e,n,r,o,a,s){this.acceptsBooleans=2===e||3===e||4===e,this.attributeName=r,this.attributeNamespace=o,this.mustUseProperty=n,this.propertyName=t,this.type=e,this.sanitizeURL=a,this.removeEmptyString=s}var Ue={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach((function(t){Ue[t]=new Qe(t,0,!1,t,null,!1,!1)})),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach((function(t){var e=t[0];Ue[e]=new Qe(e,1,!1,t[1],null,!1,!1)})),["contentEditable","draggable","spellCheck","value"].forEach((function(t){Ue[t]=new Qe(t,2,!1,t.toLowerCase(),null,!1,!1)})),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach((function(t){Ue[t]=new Qe(t,2,!1,t,null,!1,!1)})),"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach((function(t){Ue[t]=new Qe(t,3,!1,t.toLowerCase(),null,!1,!1)})),["checked","multiple","muted","selected"].forEach((function(t){Ue[t]=new Qe(t,3,!0,t,null,!1,!1)})),["capture","download"].forEach((function(t){Ue[t]=new Qe(t,4,!1,t,null,!1,!1)})),["cols","rows","size","span"].forEach((function(t){Ue[t]=new Qe(t,6,!1,t,null,!1,!1)})),["rowSpan","start"].forEach((function(t){Ue[t]=new Qe(t,5,!1,t.toLowerCase(),null,!1,!1)}));var mi=/[\-:]([a-z])/g;function gi(t){return t[1].toUpperCase()}function hi(t,e,n,r){var o=Ue.hasOwnProperty(e)?Ue[e]:null;(null!==o?0!==o.type:r||!(2"u"||function(t,e,n,r){if(null!==n&&0===n.type)return!1;switch(typeof e){case"function":case"symbol":return!0;case"boolean":return!r&&(null!==n?!n.acceptsBooleans:"data-"!==(t=t.toLowerCase().slice(0,5))&&"aria-"!==t);default:return!1}}(t,e,n,r))return!0;if(r)return!1;if(null!==n)switch(n.type){case 3:return!e;case 4:return!1===e;case 5:return isNaN(e);case 6:return isNaN(e)||1>e}return!1}(e,n,o,r)&&(n=null),r||null===o?function(t){return!!fi.call($c,t)||!fi.call(Vc,t)&&(T1.test(t)?$c[t]=!0:(Vc[t]=!0,!1))}(e)&&(null===n?t.removeAttribute(e):t.setAttribute(e,""+n)):o.mustUseProperty?t[o.propertyName]=null===n?3!==o.type&&"":n:(e=o.attributeName,r=o.attributeNamespace,null===n?t.removeAttribute(e):(n=3===(o=o.type)||4===o&&!0===n?"":""+n,r?t.setAttributeNS(r,e,n):t.setAttribute(e,n))))}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach((function(t){var e=t.replace(mi,gi);Ue[e]=new Qe(e,1,!1,t,null,!1,!1)})),"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach((function(t){var e=t.replace(mi,gi);Ue[e]=new Qe(e,1,!1,t,"http://www.w3.org/1999/xlink",!1,!1)})),["xml:base","xml:lang","xml:space"].forEach((function(t){var e=t.replace(mi,gi);Ue[e]=new Qe(e,1,!1,t,"http://www.w3.org/XML/1998/namespace",!1,!1)})),["tabIndex","crossOrigin"].forEach((function(t){Ue[t]=new Qe(t,1,!1,t.toLowerCase(),null,!1,!1)})),Ue.xlinkHref=new Qe("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach((function(t){Ue[t]=new Qe(t,1,!1,t.toLowerCase(),null,!0,!0)}));var en=qc.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,ca=Symbol.for("react.element"),ir=Symbol.for("react.portal"),lr=Symbol.for("react.fragment"),Ei=Symbol.for("react.strict_mode"),bi=Symbol.for("react.profiler"),zc=Symbol.for("react.provider"),Gc=Symbol.for("react.context"),Ai=Symbol.for("react.forward_ref"),_i=Symbol.for("react.suspense"),vi=Symbol.for("react.suspense_list"),yi=Symbol.for("react.memo"),pn=Symbol.for("react.lazy"),Zc=Symbol.for("react.offscreen"),jc=Symbol.iterator;function Qr(t){return null===t||"object"!=typeof t?null:"function"==typeof(t=jc&&t[jc]||t["@@iterator"])?t:null}var Di,ve=Object.assign;function Jr(t){if(void 0===Di)try{throw Error()}catch(n){var e=n.stack.trim().match(/\n( *(at )?)/);Di=e&&e[1]||""}return"\n"+Di+t}var Ci=!1;function Si(t,e){if(!t||Ci)return"";Ci=!0;var n=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{if(e)if(e=function(){throw Error()},Object.defineProperty(e.prototype,"props",{set:function(){throw Error()}}),"object"==typeof Reflect&&Reflect.construct){try{Reflect.construct(e,[])}catch(u){var r=u}Reflect.construct(t,[],e)}else{try{e.call()}catch(u){r=u}t.call(e.prototype)}else{try{throw Error()}catch(u){r=u}t()}}catch(u){if(u&&r&&"string"==typeof u.stack){for(var o=u.stack.split("\n"),a=r.stack.split("\n"),s=o.length-1,i=a.length-1;1<=s&&0<=i&&o[s]!==a[i];)i--;for(;1<=s&&0<=i;s--,i--)if(o[s]!==a[i]){if(1!==s||1!==i)do{if(s--,0>--i||o[s]!==a[i]){var l="\n"+o[s].replace(" at new "," at ");return t.displayName&&l.includes("")&&(l=l.replace("",t.displayName)),l}}while(1<=s&&0<=i);break}}}finally{Ci=!1,Error.prepareStackTrace=n}return(t=t?t.displayName||t.name:"")?Jr(t):""}function L1(t){switch(t.tag){case 5:return Jr(t.type);case 16:return Jr("Lazy");case 13:return Jr("Suspense");case 19:return Jr("SuspenseList");case 0:case 2:case 15:return t=Si(t.type,!1);case 11:return t=Si(t.type.render,!1);case 1:return t=Si(t.type,!0);default:return""}}function Ni(t){if(null==t)return null;if("function"==typeof t)return t.displayName||t.name||null;if("string"==typeof t)return t;switch(t){case lr:return"Fragment";case ir:return"Portal";case bi:return"Profiler";case Ei:return"StrictMode";case _i:return"Suspense";case vi:return"SuspenseList"}if("object"==typeof t)switch(t.$$typeof){case Gc:return(t.displayName||"Context")+".Consumer";case zc:return(t._context.displayName||"Context")+".Provider";case Ai:var e=t.render;return(t=t.displayName)||(t=""!==(t=e.displayName||e.name||"")?"ForwardRef("+t+")":"ForwardRef"),t;case yi:return null!==(e=t.displayName||null)?e:Ni(t.type)||"Memo";case pn:e=t._payload,t=t._init;try{return Ni(t(e))}catch{}}return null}function O1(t){var e=t.type;switch(t.tag){case 24:return"Cache";case 9:return(e.displayName||"Context")+".Consumer";case 10:return(e._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return t=(t=e.render).displayName||t.name||"",e.displayName||(""!==t?"ForwardRef("+t+")":"ForwardRef");case 7:return"Fragment";case 5:return e;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return Ni(e);case 8:return e===Ei?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if("function"==typeof e)return e.displayName||e.name||null;if("string"==typeof e)return e}return null}function fn(t){switch(typeof t){case"boolean":case"number":case"string":case"undefined":case"object":return t;default:return""}}function Wc(t){var e=t.type;return(t=t.nodeName)&&"input"===t.toLowerCase()&&("checkbox"===e||"radio"===e)}function da(t){t._valueTracker||(t._valueTracker=function(t){var e=Wc(t)?"checked":"value",n=Object.getOwnPropertyDescriptor(t.constructor.prototype,e),r=""+t[e];if(!t.hasOwnProperty(e)&&typeof n<"u"&&"function"==typeof n.get&&"function"==typeof n.set){var o=n.get,a=n.set;return Object.defineProperty(t,e,{configurable:!0,get:function(){return o.call(this)},set:function(s){r=""+s,a.call(this,s)}}),Object.defineProperty(t,e,{enumerable:n.enumerable}),{getValue:function(){return r},setValue:function(s){r=""+s},stopTracking:function(){t._valueTracker=null,delete t[e]}}}}(t))}function Kc(t){if(!t)return!1;var e=t._valueTracker;if(!e)return!0;var n=e.getValue(),r="";return t&&(r=Wc(t)?t.checked?"true":"false":t.value),(t=r)!==n&&(e.setValue(t),!0)}function pa(t){if(typeof(t=t||(typeof document<"u"?document:void 0))>"u")return null;try{return t.activeElement||t.body}catch{return t.body}}function Ti(t,e){var n=e.checked;return ve({},e,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:n??t._wrapperState.initialChecked})}function Yc(t,e){var n=null==e.defaultValue?"":e.defaultValue,r=null!=e.checked?e.checked:e.defaultChecked;n=fn(null!=e.value?e.value:n),t._wrapperState={initialChecked:r,initialValue:n,controlled:"checkbox"===e.type||"radio"===e.type?null!=e.checked:null!=e.value}}function Xc(t,e){null!=(e=e.checked)&&hi(t,"checked",e,!1)}function wi(t,e){Xc(t,e);var n=fn(e.value),r=e.type;if(null!=n)"number"===r?(0===n&&""===t.value||t.value!=n)&&(t.value=""+n):t.value!==""+n&&(t.value=""+n);else if("submit"===r||"reset"===r)return void t.removeAttribute("value");e.hasOwnProperty("value")?xi(t,e.type,n):e.hasOwnProperty("defaultValue")&&xi(t,e.type,fn(e.defaultValue)),null==e.checked&&null!=e.defaultChecked&&(t.defaultChecked=!!e.defaultChecked)}function Qc(t,e,n){if(e.hasOwnProperty("value")||e.hasOwnProperty("defaultValue")){var r=e.type;if(!("submit"!==r&&"reset"!==r||void 0!==e.value&&null!==e.value))return;e=""+t._wrapperState.initialValue,n||e===t.value||(t.value=e),t.defaultValue=e}""!==(n=t.name)&&(t.name=""),t.defaultChecked=!!t._wrapperState.initialChecked,""!==n&&(t.name=n)}function xi(t,e,n){("number"!==e||pa(t.ownerDocument)!==t)&&(null==n?t.defaultValue=""+t._wrapperState.initialValue:t.defaultValue!==""+n&&(t.defaultValue=""+n))}var eo=Array.isArray;function ur(t,e,n,r){if(t=t.options,e){e={};for(var o=0;o"+e.valueOf().toString()+"",e=fa.firstChild;t.firstChild;)t.removeChild(t.firstChild);for(;e.firstChild;)t.appendChild(e.firstChild)}},typeof MSApp<"u"&&MSApp.execUnsafeLocalFunction?function(e,n,r,o){MSApp.execUnsafeLocalFunction((function(){return t(e,n)}))}:t);function to(t,e){if(e){var n=t.firstChild;if(n&&n===t.lastChild&&3===n.nodeType)return void(n.nodeValue=e)}t.textContent=e}var no={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},I1=["Webkit","ms","Moz","O"];function od(t,e,n){return null==e||"boolean"==typeof e||""===e?"":n||"number"!=typeof e||0===e||no.hasOwnProperty(t)&&no[t]?(""+e).trim():e+"px"}function ad(t,e){for(var n in t=t.style,e)if(e.hasOwnProperty(n)){var r=0===n.indexOf("--"),o=od(n,e[n],r);"float"===n&&(n="cssFloat"),r?t.setProperty(n,o):t[n]=o}}Object.keys(no).forEach((function(t){I1.forEach((function(e){e=e+t.charAt(0).toUpperCase()+t.substring(1),no[e]=no[t]}))}));var M1=ve({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function Oi(t,e){if(e){if(M1[t]&&(null!=e.children||null!=e.dangerouslySetInnerHTML))throw Error(M(137,t));if(null!=e.dangerouslySetInnerHTML){if(null!=e.children)throw Error(M(60));if("object"!=typeof e.dangerouslySetInnerHTML||!("__html"in e.dangerouslySetInnerHTML))throw Error(M(61))}if(null!=e.style&&"object"!=typeof e.style)throw Error(M(62))}}function ki(t,e){if(-1===t.indexOf("-"))return"string"==typeof e.is;switch(t){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}var Ii=null;function Mi(t){return(t=t.target||t.srcElement||window).correspondingUseElement&&(t=t.correspondingUseElement),3===t.nodeType?t.parentNode:t}var Fi=null,cr=null,dr=null;function sd(t){if(t=So(t)){if("function"!=typeof Fi)throw Error(M(280));var e=t.stateNode;e&&(e=Fa(e),Fi(t.stateNode,t.type,e))}}function id(t){cr?dr?dr.push(t):dr=[t]:cr=t}function ld(){if(cr){var t=cr,e=dr;if(dr=cr=null,sd(t),e)for(t=0;t>>=0,0===t?32:31-(Z1(t)/j1|0)|0},Z1=Math.log,j1=Math.LN2;var ba=64,Aa=4194304;function so(t){switch(t&-t){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return 4194240&t;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return 130023424&t;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return t}}function _a(t,e){var n=t.pendingLanes;if(0===n)return 0;var r=0,o=t.suspendedLanes,a=t.pingedLanes,s=268435455&n;if(0!==s){var i=s&~o;0!==i?r=so(i):0!==(a&=s)&&(r=so(a))}else 0!==(s=n&~o)?r=so(s):0!==a&&(r=so(a));if(0===r)return 0;if(0!==e&&e!==r&&!(e&o)&&((o=r&-r)>=(a=e&-e)||16===o&&0!=(4194240&a)))return e;if(4&r&&(r|=16&n),0!==(e=t.entangledLanes))for(t=t.entanglements,e&=r;0n;n++)e.push(t);return e}function io(t,e,n){t.pendingLanes|=e,536870912!==e&&(t.suspendedLanes=0,t.pingedLanes=0),(t=t.eventTimes)[e=31-Rt(e)]=n}function $i(t,e){var n=t.entangledLanes|=e;for(t=t.entanglements;n;){var r=31-Rt(n),o=1<=ho),Fd=" ",Bd=!1;function Pd(t,e){switch(t){case"keyup":return-1!==Sh.indexOf(e.keyCode);case"keydown":return 229!==e.keyCode;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Ud(t){return"object"==typeof(t=t.detail)&&"data"in t?t.data:null}var mr=!1;var xh={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};function qd(t){var e=t&&t.nodeName&&t.nodeName.toLowerCase();return"input"===e?!!xh[t.type]:"textarea"===e}function Hd(t,e,n,r){id(r),0<(e=ka(e,"onChange")).length&&(n=new Ki("onChange","change",null,n,r),t.push({event:n,listeners:e}))}var Eo=null,bo=null;function Rh(t){ap(t,0)}function xa(t){if(Kc(Ar(t)))return t}function Lh(t,e){if("change"===t)return e}var Vd=!1;if(Jt){var tl;if(Jt){var nl="oninput"in document;if(!nl){var $d=document.createElement("div");$d.setAttribute("oninput","return;"),nl="function"==typeof $d.oninput}tl=nl}else tl=!1;Vd=tl&&(!document.documentMode||9=e)return{node:n,offset:e-t};t=r}e:{for(;n;){if(n.nextSibling){n=n.nextSibling;break e}n=n.parentNode}n=void 0}n=Zd(n)}}function Wd(t,e){return!(!t||!e)&&(t===e||(!t||3!==t.nodeType)&&(e&&3===e.nodeType?Wd(t,e.parentNode):"contains"in t?t.contains(e):!!t.compareDocumentPosition&&!!(16&t.compareDocumentPosition(e))))}function Kd(){for(var t=window,e=pa();e instanceof t.HTMLIFrameElement;){try{var n="string"==typeof e.contentWindow.location.href}catch{n=!1}if(!n)break;e=pa((t=e.contentWindow).document)}return e}function rl(t){var e=t&&t.nodeName&&t.nodeName.toLowerCase();return e&&("input"===e&&("text"===t.type||"search"===t.type||"tel"===t.type||"url"===t.type||"password"===t.type)||"textarea"===e||"true"===t.contentEditable)}function Bh(t){var e=Kd(),n=t.focusedElem,r=t.selectionRange;if(e!==n&&n&&n.ownerDocument&&Wd(n.ownerDocument.documentElement,n)){if(null!==r&&rl(n))if(e=r.start,void 0===(t=r.end)&&(t=e),"selectionStart"in n)n.selectionStart=e,n.selectionEnd=Math.min(t,n.value.length);else if((t=(e=n.ownerDocument||document)&&e.defaultView||window).getSelection){t=t.getSelection();var o=n.textContent.length,a=Math.min(r.start,o);r=void 0===r.end?a:Math.min(r.end,o),!t.extend&&a>r&&(o=r,r=a,a=o),o=jd(n,a);var s=jd(n,r);o&&s&&(1!==t.rangeCount||t.anchorNode!==o.node||t.anchorOffset!==o.offset||t.focusNode!==s.node||t.focusOffset!==s.offset)&&((e=e.createRange()).setStart(o.node,o.offset),t.removeAllRanges(),a>r?(t.addRange(e),t.extend(s.node,s.offset)):(e.setEnd(s.node,s.offset),t.addRange(e)))}for(e=[],t=n;t=t.parentNode;)1===t.nodeType&&e.push({element:t,left:t.scrollLeft,top:t.scrollTop});for("function"==typeof n.focus&&n.focus(),n=0;n=document.documentMode,gr=null,ol=null,_o=null,al=!1;function Yd(t,e,n){var r=n.window===n?n.document:9===n.nodeType?n:n.ownerDocument;al||null==gr||gr!==pa(r)||("selectionStart"in(r=gr)&&rl(r)?r={start:r.selectionStart,end:r.selectionEnd}:r={anchorNode:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection()).anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset},_o&&Ao(_o,r)||(_o=r,0<(r=ka(ol,"onSelect")).length&&(e=new Ki("onSelect","select",null,e,n),t.push({event:e,listeners:r}),e.target=gr)))}function Ra(t,e){var n={};return n[t.toLowerCase()]=e.toLowerCase(),n["Webkit"+t]="webkit"+e,n["Moz"+t]="moz"+e,n}var hr={animationend:Ra("Animation","AnimationEnd"),animationiteration:Ra("Animation","AnimationIteration"),animationstart:Ra("Animation","AnimationStart"),transitionend:Ra("Transition","TransitionEnd")},sl={},Xd={};function La(t){if(sl[t])return sl[t];if(!hr[t])return t;var n,e=hr[t];for(n in e)if(e.hasOwnProperty(n)&&n in Xd)return sl[t]=e[n];return t}Jt&&(Xd=document.createElement("div").style,"AnimationEvent"in window||(delete hr.animationend.animation,delete hr.animationiteration.animation,delete hr.animationstart.animation),"TransitionEvent"in window||delete hr.transitionend.transition);var Qd=La("animationend"),Jd=La("animationiteration"),ep=La("animationstart"),tp=La("transitionend"),np=new Map,rp="abort auxClick cancel canPlay canPlayThrough click close contextMenu copy cut drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error gotPointerCapture input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart lostPointerCapture mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing pointerCancel pointerDown pointerMove pointerOut pointerOver pointerUp progress rateChange reset resize seeked seeking stalled submit suspend timeUpdate touchCancel touchEnd touchStart volumeChange scroll toggle touchMove waiting wheel".split(" ");function An(t,e){np.set(t,e),Mn(e,[t])}for(var il=0;il_r||(t.current=El[_r],El[_r]=null,_r--)}function me(t,e){_r++,El[_r]=t.current,t.current=e}var yn={},$e=vn(yn),nt=vn(!1),Pn=yn;function vr(t,e){var n=t.type.contextTypes;if(!n)return yn;var r=t.stateNode;if(r&&r.__reactInternalMemoizedUnmaskedChildContext===e)return r.__reactInternalMemoizedMaskedChildContext;var a,o={};for(a in n)o[a]=e[a];return r&&((t=t.stateNode).__reactInternalMemoizedUnmaskedChildContext=e,t.__reactInternalMemoizedMaskedChildContext=o),o}function rt(t){return null!=(t=t.childContextTypes)}function Ba(){Ae(nt),Ae($e)}function dp(t,e,n){if($e.current!==yn)throw Error(M(168));me($e,e),me(nt,n)}function pp(t,e,n){var r=t.stateNode;if(e=e.childContextTypes,"function"!=typeof r.getChildContext)return n;for(var o in r=r.getChildContext())if(!(o in e))throw Error(M(108,O1(t)||"Unknown",o));return ve({},n,r)}function Pa(t){return t=(t=t.stateNode)&&t.__reactInternalMemoizedMergedChildContext||yn,Pn=$e.current,me($e,t),me(nt,nt.current),!0}function fp(t,e,n){var r=t.stateNode;if(!r)throw Error(M(169));n?(t=pp(t,e,Pn),r.__reactInternalMemoizedMergedChildContext=t,Ae(nt),Ae($e),me($e,t)):Ae(nt),me(nt,n)}var nn=null,Ua=!1,bl=!1;function mp(t){null===nn?nn=[t]:nn.push(t)}function Dn(){if(!bl&&null!==nn){bl=!0;var t=0,e=de;try{var n=nn;for(de=1;t>=s,o-=s,rn=1<<32-Rt(e)+o|n<R?(H=T,T=null):H=T.sibling;var I=d(h,T,E[R],_);if(null===I){null===T&&(T=H);break}t&&T&&null===I.alternate&&e(h,T),g=a(I,g,R),null===v?N=I:v.sibling=I,v=I,T=H}if(R===E.length)return n(h,T),_e&&qn(h,R),N;if(null===T){for(;RR?(H=T,T=null):H=T.sibling;var W=d(h,T,I.value,_);if(null===W){null===T&&(T=H);break}t&&T&&null===W.alternate&&e(h,T),g=a(W,g,R),null===v?N=W:v.sibling=W,v=W,T=H}if(I.done)return n(h,T),_e&&qn(h,R),N;if(null===T){for(;!I.done;R++,I=E.next())null!==(I=p(h,I.value,_))&&(g=a(I,g,R),null===v?N=I:v.sibling=I,v=I);return _e&&qn(h,R),N}for(T=r(h,T);!I.done;R++,I=E.next())null!==(I=f(T,h,R,I.value,_))&&(t&&null!==I.alternate&&T.delete(null===I.key?R:I.key),g=a(I,g,R),null===v?N=I:v.sibling=I,v=I);return t&&T.forEach((function(le){return e(h,le)})),_e&&qn(h,R),N}(h,g,E,_);Wa(h,E)}return"string"==typeof E&&""!==E||"number"==typeof E?(E=""+E,null!==g&&6===g.tag?(n(h,g.sibling),(g=o(g,E)).return=h,h=g):(n(h,g),(g=mu(E,h.mode,_)).return=h,h=g),s(h)):n(h,g)}}var Tr=xp(!0),Rp=xp(!1),To={},zt=vn(To),wo=vn(To),xo=vn(To);function Vn(t){if(t===To)throw Error(M(174));return t}function Ol(t,e){switch(me(xo,e),me(wo,t),me(zt,To),t=e.nodeType){case 9:case 11:e=(e=e.documentElement)?e.namespaceURI:Li(null,"");break;default:e=Li(e=(t=8===t?e.parentNode:e).namespaceURI||null,t=t.tagName)}Ae(zt),me(zt,e)}function wr(){Ae(zt),Ae(wo),Ae(xo)}function Lp(t){Vn(xo.current);var e=Vn(zt.current),n=Li(e,t.type);e!==n&&(me(wo,t),me(zt,n))}function kl(t){wo.current===t&&(Ae(zt),Ae(wo))}var ye=vn(0);function Ka(t){for(var e=t;null!==e;){if(13===e.tag){var n=e.memoizedState;if(null!==n&&(null===(n=n.dehydrated)||"$?"===n.data||"$!"===n.data))return e}else if(19===e.tag&&void 0!==e.memoizedProps.revealOrder){if(128&e.flags)return e}else if(null!==e.child){e.child.return=e,e=e.child;continue}if(e===t)break;for(;null===e.sibling;){if(null===e.return||e.return===t)return null;e=e.return}e.sibling.return=e.return,e=e.sibling}return null}var Il=[];function Ml(){for(var t=0;tn?n:4,t(!0);var r=Fl.transition;Fl.transition={};try{t(!1),e()}finally{de=n,Fl.transition=r}}function Kp(){return Ct().memoizedState}function Jh(t,e,n){var r=xn(t);if(n={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null},Yp(t))Xp(e,n);else if(null!==(n=_p(t,e,n,r))){Ft(n,t,r,et()),Qp(n,e,r)}}function eE(t,e,n){var r=xn(t),o={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null};if(Yp(t))Xp(e,o);else{var a=t.alternate;if(0===t.lanes&&(null===a||0===a.lanes)&&null!==(a=e.lastRenderedReducer))try{var s=e.lastRenderedState,i=a(s,n);if(o.hasEagerState=!0,o.eagerState=i,Lt(i,s)){var l=e.interleaved;return null===l?(o.next=o,wl(e)):(o.next=l.next,l.next=o),void(e.interleaved=o)}}catch{}null!==(n=_p(t,e,o,r))&&(Ft(n,t,r,o=et()),Qp(n,e,r))}}function Yp(t){var e=t.alternate;return t===De||null!==e&&e===De}function Xp(t,e){Ro=Xa=!0;var n=t.pending;null===n?e.next=e:(e.next=n.next,n.next=e),t.pending=e}function Qp(t,e,n){if(4194240&n){var r=e.lanes;n|=r&=t.pendingLanes,e.lanes=n,$i(t,n)}}var es={readContext:Dt,useCallback:ze,useContext:ze,useEffect:ze,useImperativeHandle:ze,useInsertionEffect:ze,useLayoutEffect:ze,useMemo:ze,useReducer:ze,useRef:ze,useState:ze,useDebugValue:ze,useDeferredValue:ze,useTransition:ze,useMutableSource:ze,useSyncExternalStore:ze,useId:ze,unstable_isNewReconciler:!1},tE={readContext:Dt,useCallback:function(t,e){return Gt().memoizedState=[t,void 0===e?null:e],t},useContext:Dt,useEffect:Hp,useImperativeHandle:function(t,e,n){return n=null!=n?n.concat([t]):null,Qa(4194308,4,zp.bind(null,e,t),n)},useLayoutEffect:function(t,e){return Qa(4194308,4,t,e)},useInsertionEffect:function(t,e){return Qa(4,2,t,e)},useMemo:function(t,e){var n=Gt();return e=void 0===e?null:e,t=t(),n.memoizedState=[t,e],t},useReducer:function(t,e,n){var r=Gt();return e=void 0!==n?n(e):e,r.memoizedState=r.baseState=e,t={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:t,lastRenderedState:e},r.queue=t,t=t.dispatch=Jh.bind(null,De,t),[r.memoizedState,t]},useRef:function(t){return t={current:t},Gt().memoizedState=t},useState:Up,useDebugValue:$l,useDeferredValue:function(t){return Gt().memoizedState=t},useTransition:function(){var t=Up(!1),e=t[0];return t=Qh.bind(null,t[1]),Gt().memoizedState=t,[e,t]},useMutableSource:function(){},useSyncExternalStore:function(t,e,n){var r=De,o=Gt();if(_e){if(void 0===n)throw Error(M(407));n=n()}else{if(n=e(),null===Ie)throw Error(M(349));30&$n||Ip(r,e,n)}o.memoizedState=n;var a={value:n,getSnapshot:e};return o.queue=a,Hp(Fp.bind(null,r,a,t),[t]),r.flags|=2048,ko(9,Mp.bind(null,r,a,n,e),void 0,null),n},useId:function(){var t=Gt(),e=Ie.identifierPrefix;if(_e){var n=on;e=":"+e+"R"+(n=(rn&~(1<<32-Rt(rn)-1)).toString(32)+n),0<(n=Lo++)&&(e+="H"+n.toString(32)),e+=":"}else e=":"+e+"r"+(n=Xh++).toString(32)+":";return t.memoizedState=e},unstable_isNewReconciler:!1},nE={readContext:Dt,useCallback:Zp,useContext:Dt,useEffect:Vl,useImperativeHandle:Gp,useInsertionEffect:Vp,useLayoutEffect:$p,useMemo:jp,useReducer:ql,useRef:qp,useState:function(){return ql(Oo)},useDebugValue:$l,useDeferredValue:function(t){return Wp(Ct(),Re.memoizedState,t)},useTransition:function(){return[ql(Oo)[0],Ct().memoizedState]},useMutableSource:Op,useSyncExternalStore:kp,useId:Kp,unstable_isNewReconciler:!1},rE={readContext:Dt,useCallback:Zp,useContext:Dt,useEffect:Vl,useImperativeHandle:Gp,useInsertionEffect:Vp,useLayoutEffect:$p,useMemo:jp,useReducer:Hl,useRef:qp,useState:function(){return Hl(Oo)},useDebugValue:$l,useDeferredValue:function(t){var e=Ct();return null===Re?e.memoizedState=t:Wp(e,Re.memoizedState,t)},useTransition:function(){return[Hl(Oo)[0],Ct().memoizedState]},useMutableSource:Op,useSyncExternalStore:kp,useId:Kp,unstable_isNewReconciler:!1};function xr(t,e){try{var n="",r=e;do{n+=L1(r),r=r.return}while(r);var o=n}catch(a){o="\nError generating stack: "+a.message+"\n"+a.stack}return{value:t,source:e,stack:o,digest:null}}function zl(t,e,n){return{value:t,source:null,stack:n??null,digest:e??null}}function Gl(t,e){try{console.error(e.value)}catch(n){setTimeout((function(){throw n}))}}var oE="function"==typeof WeakMap?WeakMap:Map;function Jp(t,e,n){(n=sn(-1,n)).tag=3,n.payload={element:null};var r=e.value;return n.callback=function(){is||(is=!0,su=r),Gl(0,e)},n}function e0(t,e,n){(n=sn(-1,n)).tag=3;var r=t.type.getDerivedStateFromError;if("function"==typeof r){var o=e.value;n.payload=function(){return r(o)},n.callback=function(){Gl(0,e)}}var a=t.stateNode;return null!==a&&"function"==typeof a.componentDidCatch&&(n.callback=function(){Gl(0,e),"function"!=typeof r&&(null===Tn?Tn=new Set([this]):Tn.add(this));var s=e.stack;this.componentDidCatch(e.value,{componentStack:null!==s?s:""})}),n}function t0(t,e,n){var r=t.pingCache;if(null===r){r=t.pingCache=new oE;var o=new Set;r.set(e,o)}else void 0===(o=r.get(e))&&(o=new Set,r.set(e,o));o.has(n)||(o.add(n),t=bE.bind(null,t,e,n),e.then(t,t))}function n0(t){do{var e;if((e=13===t.tag)&&(e=null===(e=t.memoizedState)||null!==e.dehydrated),e)return t;t=t.return}while(null!==t);return null}function r0(t,e,n,r,o){return 1&t.mode?(t.flags|=65536,t.lanes=o,t):(t===e?t.flags|=65536:(t.flags|=128,n.flags|=131072,n.flags&=-52805,1===n.tag&&(null===n.alternate?n.tag=17:((e=sn(-1,1)).tag=2,Sn(n,e,1))),n.lanes|=1),t)}var aE=en.ReactCurrentOwner,ot=!1;function Je(t,e,n,r){e.child=null===t?Rp(e,null,n,r):Tr(e,t.child,n,r)}function o0(t,e,n,r,o){n=n.render;var a=e.ref;return Nr(e,o),r=Pl(t,e,n,r,a,o),n=Ul(),null===t||ot?(_e&&n&&Al(e),e.flags|=1,Je(t,e,r,o),e.child):(e.updateQueue=t.updateQueue,e.flags&=-2053,t.lanes&=~o,ln(t,e,o))}function a0(t,e,n,r,o){if(null===t){var a=n.type;return"function"!=typeof a||fu(a)||void 0!==a.defaultProps||null!==n.compare||void 0!==n.defaultProps?((t=fs(n.type,null,r,e,e.mode,o)).ref=e.ref,t.return=e,e.child=t):(e.tag=15,e.type=a,s0(t,e,a,r,o))}if(a=t.child,!(t.lanes&o)){var s=a.memoizedProps;if((n=null!==(n=n.compare)?n:Ao)(s,r)&&t.ref===e.ref)return ln(t,e,o)}return e.flags|=1,(t=Ln(a,r)).ref=e.ref,t.return=e,e.child=t}function s0(t,e,n,r,o){if(null!==t){var a=t.memoizedProps;if(Ao(a,r)&&t.ref===e.ref){if(ot=!1,e.pendingProps=r=a,0==(t.lanes&o))return e.lanes=t.lanes,ln(t,e,o);131072&t.flags&&(ot=!0)}}return Zl(t,e,n,r,o)}function i0(t,e,n){var r=e.pendingProps,o=r.children,a=null!==t?t.memoizedState:null;if("hidden"===r.mode)if(1&e.mode){if(!(1073741824&n))return t=null!==a?a.baseLanes|n:n,e.lanes=e.childLanes=1073741824,e.memoizedState={baseLanes:t,cachePool:null,transitions:null},e.updateQueue=null,me(Lr,gt),gt|=t,null;e.memoizedState={baseLanes:0,cachePool:null,transitions:null},r=null!==a?a.baseLanes:n,me(Lr,gt),gt|=r}else e.memoizedState={baseLanes:0,cachePool:null,transitions:null},me(Lr,gt),gt|=n;else null!==a?(r=a.baseLanes|n,e.memoizedState=null):r=n,me(Lr,gt),gt|=r;return Je(t,e,o,n),e.child}function l0(t,e){var n=e.ref;(null===t&&null!==n||null!==t&&t.ref!==n)&&(e.flags|=512,e.flags|=2097152)}function Zl(t,e,n,r,o){var a=rt(n)?Pn:$e.current;return a=vr(e,a),Nr(e,o),n=Pl(t,e,n,r,a,o),r=Ul(),null===t||ot?(_e&&r&&Al(e),e.flags|=1,Je(t,e,n,o),e.child):(e.updateQueue=t.updateQueue,e.flags&=-2053,t.lanes&=~o,ln(t,e,o))}function u0(t,e,n,r,o){if(rt(n)){var a=!0;Pa(e)}else a=!1;if(Nr(e,o),null===e.stateNode)ns(t,e),Np(e,n,r),Ll(e,n,r,o),r=!0;else if(null===t){var s=e.stateNode,i=e.memoizedProps;s.props=i;var l=s.context,u=n.contextType;"object"==typeof u&&null!==u?u=Dt(u):u=vr(e,u=rt(n)?Pn:$e.current);var c=n.getDerivedStateFromProps,p="function"==typeof c||"function"==typeof s.getSnapshotBeforeUpdate;p||"function"!=typeof s.UNSAFE_componentWillReceiveProps&&"function"!=typeof s.componentWillReceiveProps||(i!==r||l!==u)&&Tp(e,s,r,u),Cn=!1;var d=e.memoizedState;s.state=d,Za(e,r,s,o),l=e.memoizedState,i!==r||d!==l||nt.current||Cn?("function"==typeof c&&(Rl(e,n,c,r),l=e.memoizedState),(i=Cn||Sp(e,n,i,r,d,l,u))?(p||"function"!=typeof s.UNSAFE_componentWillMount&&"function"!=typeof s.componentWillMount||("function"==typeof s.componentWillMount&&s.componentWillMount(),"function"==typeof s.UNSAFE_componentWillMount&&s.UNSAFE_componentWillMount()),"function"==typeof s.componentDidMount&&(e.flags|=4194308)):("function"==typeof s.componentDidMount&&(e.flags|=4194308),e.memoizedProps=r,e.memoizedState=l),s.props=r,s.state=l,s.context=u,r=i):("function"==typeof s.componentDidMount&&(e.flags|=4194308),r=!1)}else{s=e.stateNode,vp(t,e),i=e.memoizedProps,u=e.type===e.elementType?i:kt(e.type,i),s.props=u,p=e.pendingProps,d=s.context,"object"==typeof(l=n.contextType)&&null!==l?l=Dt(l):l=vr(e,l=rt(n)?Pn:$e.current);var f=n.getDerivedStateFromProps;(c="function"==typeof f||"function"==typeof s.getSnapshotBeforeUpdate)||"function"!=typeof s.UNSAFE_componentWillReceiveProps&&"function"!=typeof s.componentWillReceiveProps||(i!==p||d!==l)&&Tp(e,s,r,l),Cn=!1,d=e.memoizedState,s.state=d,Za(e,r,s,o);var b=e.memoizedState;i!==p||d!==b||nt.current||Cn?("function"==typeof f&&(Rl(e,n,f,r),b=e.memoizedState),(u=Cn||Sp(e,n,u,r,d,b,l)||!1)?(c||"function"!=typeof s.UNSAFE_componentWillUpdate&&"function"!=typeof s.componentWillUpdate||("function"==typeof s.componentWillUpdate&&s.componentWillUpdate(r,b,l),"function"==typeof s.UNSAFE_componentWillUpdate&&s.UNSAFE_componentWillUpdate(r,b,l)),"function"==typeof s.componentDidUpdate&&(e.flags|=4),"function"==typeof s.getSnapshotBeforeUpdate&&(e.flags|=1024)):("function"!=typeof s.componentDidUpdate||i===t.memoizedProps&&d===t.memoizedState||(e.flags|=4),"function"!=typeof s.getSnapshotBeforeUpdate||i===t.memoizedProps&&d===t.memoizedState||(e.flags|=1024),e.memoizedProps=r,e.memoizedState=b),s.props=r,s.state=b,s.context=l,r=u):("function"!=typeof s.componentDidUpdate||i===t.memoizedProps&&d===t.memoizedState||(e.flags|=4),"function"!=typeof s.getSnapshotBeforeUpdate||i===t.memoizedProps&&d===t.memoizedState||(e.flags|=1024),r=!1)}return jl(t,e,n,r,a,o)}function jl(t,e,n,r,o,a){l0(t,e);var s=0!=(128&e.flags);if(!r&&!s)return o&&fp(e,n,!1),ln(t,e,a);r=e.stateNode,aE.current=e;var i=s&&"function"!=typeof n.getDerivedStateFromError?null:r.render();return e.flags|=1,null!==t&&s?(e.child=Tr(e,t.child,null,a),e.child=Tr(e,null,i,a)):Je(t,e,i,a),e.memoizedState=r.state,o&&fp(e,n,!0),e.child}function c0(t){var e=t.stateNode;e.pendingContext?dp(0,e.pendingContext,e.pendingContext!==e.context):e.context&&dp(0,e.context,!1),Ol(t,e.containerInfo)}function d0(t,e,n,r,o){return Cr(),Dl(o),e.flags|=256,Je(t,e,n,r),e.child}var g0,Ql,h0,E0,Wl={dehydrated:null,treeContext:null,retryLane:0};function Kl(t){return{baseLanes:t,cachePool:null,transitions:null}}function p0(t,e,n){var i,r=e.pendingProps,o=ye.current,a=!1,s=0!=(128&e.flags);if((i=s)||(i=(null===t||null!==t.memoizedState)&&0!=(2&o)),i?(a=!0,e.flags&=-129):(null===t||null!==t.memoizedState)&&(o|=1),me(ye,1&o),null===t)return yl(e),null!==(t=e.memoizedState)&&null!==(t=t.dehydrated)?(1&e.mode?"$!"===t.data?e.lanes=8:e.lanes=1073741824:e.lanes=1,null):(s=r.children,t=r.fallback,a?(r=e.mode,a=e.child,s={mode:"hidden",children:s},1&r||null===a?a=ms(s,r,0,null):(a.childLanes=0,a.pendingProps=s),t=Wn(t,r,n,null),a.return=e,t.return=e,a.sibling=t,e.child=a,e.child.memoizedState=Kl(n),e.memoizedState=Wl,t):Yl(e,s));if(null!==(o=t.memoizedState)&&null!==(i=o.dehydrated))return function(t,e,n,r,o,a,s){if(n)return 256&e.flags?(e.flags&=-257,r=zl(Error(M(422))),ts(t,e,s,r)):null!==e.memoizedState?(e.child=t.child,e.flags|=128,null):(a=r.fallback,o=e.mode,r=ms({mode:"visible",children:r.children},o,0,null),a=Wn(a,o,s,null),a.flags|=2,r.return=e,a.return=e,r.sibling=a,e.child=r,1&e.mode&&Tr(e,t.child,null,s),e.child.memoizedState=Kl(s),e.memoizedState=Wl,a);if(!(1&e.mode))return ts(t,e,s,null);if("$!"===o.data){if(r=o.nextSibling&&o.nextSibling.dataset)var i=r.dgst;return r=i,ts(t,e,s,r=zl(a=Error(M(419)),r,void 0))}if(i=0!=(s&t.childLanes),ot||i){if(null!==(r=Ie)){switch(s&-s){case 4:o=2;break;case 16:o=8;break;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:o=32;break;case 536870912:o=268435456;break;default:o=0}0!==(o=o&(r.suspendedLanes|s)?0:o)&&o!==a.retryLane&&(a.retryLane=o,an(t,o),Ft(r,t,o,-1))}return pu(),ts(t,e,s,r=zl(Error(M(421))))}return"$?"===o.data?(e.flags|=128,e.child=t.child,e=AE.bind(null,t),o._reactRetry=e,null):(t=a.treeContext,mt=_n(o.nextSibling),ft=e,_e=!0,Ot=null,null!==t&&(vt[yt++]=rn,vt[yt++]=on,vt[yt++]=Un,rn=t.id,on=t.overflow,Un=e),e=Yl(e,r.children),e.flags|=4096,e)}(t,e,s,r,i,o,n);if(a){a=r.fallback,s=e.mode,i=(o=t.child).sibling;var l={mode:"hidden",children:r.children};return 1&s||e.child===o?(r=Ln(o,l)).subtreeFlags=14680064&o.subtreeFlags:((r=e.child).childLanes=0,r.pendingProps=l,e.deletions=null),null!==i?a=Ln(i,a):(a=Wn(a,s,n,null)).flags|=2,a.return=e,r.return=e,r.sibling=a,e.child=r,r=a,a=e.child,s=null===(s=t.child.memoizedState)?Kl(n):{baseLanes:s.baseLanes|n,cachePool:null,transitions:s.transitions},a.memoizedState=s,a.childLanes=t.childLanes&~n,e.memoizedState=Wl,r}return t=(a=t.child).sibling,r=Ln(a,{mode:"visible",children:r.children}),!(1&e.mode)&&(r.lanes=n),r.return=e,r.sibling=null,null!==t&&(null===(n=e.deletions)?(e.deletions=[t],e.flags|=16):n.push(t)),e.child=r,e.memoizedState=null,r}function Yl(t,e){return(e=ms({mode:"visible",children:e},t.mode,0,null)).return=t,t.child=e}function ts(t,e,n,r){return null!==r&&Dl(r),Tr(e,t.child,null,n),(t=Yl(e,e.pendingProps.children)).flags|=2,e.memoizedState=null,t}function f0(t,e,n){t.lanes|=e;var r=t.alternate;null!==r&&(r.lanes|=e),Tl(t.return,e,n)}function Xl(t,e,n,r,o){var a=t.memoizedState;null===a?t.memoizedState={isBackwards:e,rendering:null,renderingStartTime:0,last:r,tail:n,tailMode:o}:(a.isBackwards=e,a.rendering=null,a.renderingStartTime=0,a.last=r,a.tail=n,a.tailMode=o)}function m0(t,e,n){var r=e.pendingProps,o=r.revealOrder,a=r.tail;if(Je(t,e,r.children,n),2&(r=ye.current))r=1&r|2,e.flags|=128;else{if(null!==t&&128&t.flags)e:for(t=e.child;null!==t;){if(13===t.tag)null!==t.memoizedState&&f0(t,n,e);else if(19===t.tag)f0(t,n,e);else if(null!==t.child){t.child.return=t,t=t.child;continue}if(t===e)break e;for(;null===t.sibling;){if(null===t.return||t.return===e)break e;t=t.return}t.sibling.return=t.return,t=t.sibling}r&=1}if(me(ye,r),1&e.mode)switch(o){case"forwards":for(n=e.child,o=null;null!==n;)null!==(t=n.alternate)&&null===Ka(t)&&(o=n),n=n.sibling;null===(n=o)?(o=e.child,e.child=null):(o=n.sibling,n.sibling=null),Xl(e,!1,o,n,a);break;case"backwards":for(n=null,o=e.child,e.child=null;null!==o;){if(null!==(t=o.alternate)&&null===Ka(t)){e.child=o;break}t=o.sibling,o.sibling=n,n=o,o=t}Xl(e,!0,n,null,a);break;case"together":Xl(e,!1,null,null,void 0);break;default:e.memoizedState=null}else e.memoizedState=null;return e.child}function ns(t,e){!(1&e.mode)&&null!==t&&(t.alternate=null,e.alternate=null,e.flags|=2)}function ln(t,e,n){if(null!==t&&(e.dependencies=t.dependencies),zn|=e.lanes,!(n&e.childLanes))return null;if(null!==t&&e.child!==t.child)throw Error(M(153));if(null!==e.child){for(n=Ln(t=e.child,t.pendingProps),e.child=n,n.return=e;null!==t.sibling;)t=t.sibling,(n=n.sibling=Ln(t,t.pendingProps)).return=e;n.sibling=null}return e.child}function Io(t,e){if(!_e)switch(t.tailMode){case"hidden":e=t.tail;for(var n=null;null!==e;)null!==e.alternate&&(n=e),e=e.sibling;null===n?t.tail=null:n.sibling=null;break;case"collapsed":n=t.tail;for(var r=null;null!==n;)null!==n.alternate&&(r=n),n=n.sibling;null===r?e||null===t.tail?t.tail=null:t.tail.sibling=null:r.sibling=null}}function Ge(t){var e=null!==t.alternate&&t.alternate.child===t.child,n=0,r=0;if(e)for(var o=t.child;null!==o;)n|=o.lanes|o.childLanes,r|=14680064&o.subtreeFlags,r|=14680064&o.flags,o.return=t,o=o.sibling;else for(o=t.child;null!==o;)n|=o.lanes|o.childLanes,r|=o.subtreeFlags,r|=o.flags,o.return=t,o=o.sibling;return t.subtreeFlags|=r,t.childLanes=n,e}function lE(t,e,n){var r=e.pendingProps;switch(_l(e),e.tag){case 2:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return Ge(e),null;case 1:case 17:return rt(e.type)&&Ba(),Ge(e),null;case 3:return r=e.stateNode,wr(),Ae(nt),Ae($e),Ml(),r.pendingContext&&(r.context=r.pendingContext,r.pendingContext=null),(null===t||null===t.child)&&(Va(e)?e.flags|=4:null===t||t.memoizedState.isDehydrated&&!(256&e.flags)||(e.flags|=1024,null!==Ot&&(uu(Ot),Ot=null))),Ql(t,e),Ge(e),null;case 5:kl(e);var o=Vn(xo.current);if(n=e.type,null!==t&&null!=e.stateNode)h0(t,e,n,r,o),t.ref!==e.ref&&(e.flags|=512,e.flags|=2097152);else{if(!r){if(null===e.stateNode)throw Error(M(166));return Ge(e),null}if(t=Vn(zt.current),Va(e)){r=e.stateNode,n=e.type;var a=e.memoizedProps;switch(r[$t]=e,r[Co]=a,t=0!=(1&e.mode),n){case"dialog":be("cancel",r),be("close",r);break;case"iframe":case"object":case"embed":be("load",r);break;case"video":case"audio":for(o=0;o<\/script>",t=t.removeChild(t.firstChild)):"string"==typeof r.is?t=s.createElement(n,{is:r.is}):(t=s.createElement(n),"select"===n&&(s=t,r.multiple?s.multiple=!0:r.size&&(s.size=r.size))):t=s.createElementNS(t,n),t[$t]=e,t[Co]=r,g0(t,e,!1,!1),e.stateNode=t;e:{switch(s=ki(n,r),n){case"dialog":be("cancel",t),be("close",t),o=r;break;case"iframe":case"object":case"embed":be("load",t),o=r;break;case"video":case"audio":for(o=0;oOr&&(e.flags|=128,r=!0,Io(a,!1),e.lanes=4194304)}else{if(!r)if(null!==(t=Ka(s))){if(e.flags|=128,r=!0,null!==(n=t.updateQueue)&&(e.updateQueue=n,e.flags|=4),Io(a,!0),null===a.tail&&"hidden"===a.tailMode&&!s.alternate&&!_e)return Ge(e),null}else 2*Te()-a.renderingStartTime>Or&&1073741824!==n&&(e.flags|=128,r=!0,Io(a,!1),e.lanes=4194304);a.isBackwards?(s.sibling=e.child,e.child=s):(null!==(n=a.last)?n.sibling=s:e.child=s,a.last=s)}return null!==a.tail?(e=a.tail,a.rendering=e,a.tail=e.sibling,a.renderingStartTime=Te(),e.sibling=null,n=ye.current,me(ye,r?1&n|2:1&n),e):(Ge(e),null);case 22:case 23:return du(),r=null!==e.memoizedState,null!==t&&null!==t.memoizedState!==r&&(e.flags|=8192),r&&1&e.mode?1073741824>&&(Ge(e),6&e.subtreeFlags&&(e.flags|=8192)):Ge(e),null;case 24:case 25:return null}throw Error(M(156,e.tag))}function uE(t,e){switch(_l(e),e.tag){case 1:return rt(e.type)&&Ba(),65536&(t=e.flags)?(e.flags=-65537&t|128,e):null;case 3:return wr(),Ae(nt),Ae($e),Ml(),65536&(t=e.flags)&&!(128&t)?(e.flags=-65537&t|128,e):null;case 5:return kl(e),null;case 13:if(Ae(ye),null!==(t=e.memoizedState)&&null!==t.dehydrated){if(null===e.alternate)throw Error(M(340));Cr()}return 65536&(t=e.flags)?(e.flags=-65537&t|128,e):null;case 19:return Ae(ye),null;case 4:return wr(),null;case 10:return Nl(e.type._context),null;case 22:case 23:return du(),null;default:return null}}g0=function(t,e){for(var n=e.child;null!==n;){if(5===n.tag||6===n.tag)t.appendChild(n.stateNode);else if(4!==n.tag&&null!==n.child){n.child.return=n,n=n.child;continue}if(n===e)break;for(;null===n.sibling;){if(null===n.return||n.return===e)return;n=n.return}n.sibling.return=n.return,n=n.sibling}},Ql=function(){},h0=function(t,e,n,r){var o=t.memoizedProps;if(o!==r){t=e.stateNode,Vn(zt.current);var s,a=null;switch(n){case"input":o=Ti(t,o),r=Ti(t,r),a=[];break;case"select":o=ve({},o,{value:void 0}),r=ve({},r,{value:void 0}),a=[];break;case"textarea":o=Ri(t,o),r=Ri(t,r),a=[];break;default:"function"!=typeof o.onClick&&"function"==typeof r.onClick&&(t.onclick=Ma)}for(u in Oi(n,r),n=null,o)if(!r.hasOwnProperty(u)&&o.hasOwnProperty(u)&&null!=o[u])if("style"===u){var i=o[u];for(s in i)i.hasOwnProperty(s)&&(n||(n={}),n[s]="")}else"dangerouslySetInnerHTML"!==u&&"children"!==u&&"suppressContentEditableWarning"!==u&&"suppressHydrationWarning"!==u&&"autoFocus"!==u&&(Xr.hasOwnProperty(u)?a||(a=[]):(a=a||[]).push(u,null));for(u in r){var l=r[u];if(i=null!=o?o[u]:void 0,r.hasOwnProperty(u)&&l!==i&&(null!=l||null!=i))if("style"===u)if(i){for(s in i)!i.hasOwnProperty(s)||l&&l.hasOwnProperty(s)||(n||(n={}),n[s]="");for(s in l)l.hasOwnProperty(s)&&i[s]!==l[s]&&(n||(n={}),n[s]=l[s])}else n||(a||(a=[]),a.push(u,n)),n=l;else"dangerouslySetInnerHTML"===u?(l=l?l.__html:void 0,i=i?i.__html:void 0,null!=l&&i!==l&&(a=a||[]).push(u,l)):"children"===u?"string"!=typeof l&&"number"!=typeof l||(a=a||[]).push(u,""+l):"suppressContentEditableWarning"!==u&&"suppressHydrationWarning"!==u&&(Xr.hasOwnProperty(u)?(null!=l&&"onScroll"===u&&be("scroll",t),a||i===l||(a=[])):(a=a||[]).push(u,l))}n&&(a=a||[]).push("style",n);var u=a;(e.updateQueue=u)&&(e.flags|=4)}},E0=function(t,e,n,r){n!==r&&(e.flags|=4)};var rs=!1,Ze=!1,cE="function"==typeof WeakSet?WeakSet:Set,q=null;function Rr(t,e){var n=t.ref;if(null!==n)if("function"==typeof n)try{n(null)}catch(r){Se(t,e,r)}else n.current=null}function Jl(t,e,n){try{n()}catch(r){Se(t,e,r)}}var b0=!1;function Mo(t,e,n){var r=e.updateQueue;if(null!==(r=null!==r?r.lastEffect:null)){var o=r=r.next;do{if((o.tag&t)===t){var a=o.destroy;o.destroy=void 0,void 0!==a&&Jl(e,n,a)}o=o.next}while(o!==r)}}function os(t,e){if(null!==(e=null!==(e=e.updateQueue)?e.lastEffect:null)){var n=e=e.next;do{if((n.tag&t)===t){var r=n.create;n.destroy=r()}n=n.next}while(n!==e)}}function eu(t){var e=t.ref;if(null!==e){var n=t.stateNode;t.tag,t=n,"function"==typeof e?e(t):e.current=t}}function A0(t){var e=t.alternate;null!==e&&(t.alternate=null,A0(e)),t.child=null,t.deletions=null,t.sibling=null,5===t.tag&&(null!==(e=t.stateNode)&&(delete e[$t],delete e[Co],delete e[hl],delete e[jh],delete e[Wh])),t.stateNode=null,t.return=null,t.dependencies=null,t.memoizedProps=null,t.memoizedState=null,t.pendingProps=null,t.stateNode=null,t.updateQueue=null}function _0(t){return 5===t.tag||3===t.tag||4===t.tag}function v0(t){e:for(;;){for(;null===t.sibling;){if(null===t.return||_0(t.return))return null;t=t.return}for(t.sibling.return=t.return,t=t.sibling;5!==t.tag&&6!==t.tag&&18!==t.tag;){if(2&t.flags||null===t.child||4===t.tag)continue e;t.child.return=t,t=t.child}if(!(2&t.flags))return t.stateNode}}function tu(t,e,n){var r=t.tag;if(5===r||6===r)t=t.stateNode,e?8===n.nodeType?n.parentNode.insertBefore(t,e):n.insertBefore(t,e):(8===n.nodeType?(e=n.parentNode).insertBefore(t,n):(e=n).appendChild(t),null!=(n=n._reactRootContainer)||null!==e.onclick||(e.onclick=Ma));else if(4!==r&&null!==(t=t.child))for(tu(t,e,n),t=t.sibling;null!==t;)tu(t,e,n),t=t.sibling}function nu(t,e,n){var r=t.tag;if(5===r||6===r)t=t.stateNode,e?n.insertBefore(t,e):n.appendChild(t);else if(4!==r&&null!==(t=t.child))for(nu(t,e,n),t=t.sibling;null!==t;)nu(t,e,n),t=t.sibling}var qe=null,It=!1;function Nn(t,e,n){for(n=n.child;null!==n;)y0(t,e,n),n=n.sibling}function y0(t,e,n){if(Vt&&"function"==typeof Vt.onCommitFiberUnmount)try{Vt.onCommitFiberUnmount(Ea,n)}catch{}switch(n.tag){case 5:Ze||Rr(n,e);case 6:var r=qe,o=It;qe=null,Nn(t,e,n),It=o,null!==(qe=r)&&(It?(t=qe,n=n.stateNode,8===t.nodeType?t.parentNode.removeChild(n):t.removeChild(n)):qe.removeChild(n.stateNode));break;case 18:null!==qe&&(It?(t=qe,n=n.stateNode,8===t.nodeType?gl(t.parentNode,n):1===t.nodeType&&gl(t,n),fo(t)):gl(qe,n.stateNode));break;case 4:r=qe,o=It,qe=n.stateNode.containerInfo,It=!0,Nn(t,e,n),qe=r,It=o;break;case 0:case 11:case 14:case 15:if(!Ze&&(null!==(r=n.updateQueue)&&null!==(r=r.lastEffect))){o=r=r.next;do{var a=o,s=a.destroy;a=a.tag,void 0!==s&&(2&a||4&a)&&Jl(n,e,s),o=o.next}while(o!==r)}Nn(t,e,n);break;case 1:if(!Ze&&(Rr(n,e),"function"==typeof(r=n.stateNode).componentWillUnmount))try{r.props=n.memoizedProps,r.state=n.memoizedState,r.componentWillUnmount()}catch(i){Se(n,e,i)}Nn(t,e,n);break;case 21:Nn(t,e,n);break;case 22:1&n.mode?(Ze=(r=Ze)||null!==n.memoizedState,Nn(t,e,n),Ze=r):Nn(t,e,n);break;default:Nn(t,e,n)}}function D0(t){var e=t.updateQueue;if(null!==e){t.updateQueue=null;var n=t.stateNode;null===n&&(n=t.stateNode=new cE),e.forEach((function(r){var o=_E.bind(null,t,r);n.has(r)||(n.add(r),r.then(o,o))}))}}function Mt(t,e){var n=e.deletions;if(null!==n)for(var r=0;ro&&(o=s),r&=~a}if(r=o,10<(r=(120>(r=Te()-r)?120:480>r?480:1080>r?1080:1920>r?1920:3e3>r?3e3:4320>r?4320:1960*fE(r/1960))-r)){t.timeoutHandle=ml(jn.bind(null,t,at,un),r);break}jn(t,at,un);break;default:throw Error(M(329))}}}return st(t,Te()),t.callbackNode===n?x0.bind(null,t):null}function lu(t,e){var n=Bo;return t.current.memoizedState.isDehydrated&&(Zn(t,e).flags|=256),2!==(t=ps(t,e))&&(e=at,at=n,null!==e&&uu(e)),t}function uu(t){null===at?at=t:at.push.apply(at,t)}function Rn(t,e){for(e&=~ou,e&=~ss,t.suspendedLanes|=e,t.pingedLanes&=~e,t=t.expirationTimes;0t?16:t,null===wn)var r=!1;else{if(t=wn,wn=null,us=0,6&oe)throw Error(M(331));var o=oe;for(oe|=4,q=t.current;null!==q;){var a=q,s=a.child;if(16&q.flags){var i=a.deletions;if(null!==i){for(var l=0;lTe()-au?Zn(t,0):ou|=n),st(t,e)}function F0(t,e){0===e&&(1&t.mode?(e=Aa,!(130023424&(Aa<<=1))&&(Aa=4194304)):e=1);var n=et();null!==(t=an(t,e))&&(io(t,e,n),st(t,n))}function AE(t){var e=t.memoizedState,n=0;null!==e&&(n=e.retryLane),F0(t,n)}function _E(t,e){var n=0;switch(t.tag){case 13:var r=t.stateNode,o=t.memoizedState;null!==o&&(n=o.retryLane);break;case 19:r=t.stateNode;break;default:throw Error(M(314))}null!==r&&r.delete(e),F0(t,n)}function P0(t,e){return hd(t,e)}function vE(t,e,n,r){this.tag=t,this.key=n,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=e,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=r,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function Nt(t,e,n,r){return new vE(t,e,n,r)}function fu(t){return!(!(t=t.prototype)||!t.isReactComponent)}function Ln(t,e){var n=t.alternate;return null===n?((n=Nt(t.tag,e,t.key,t.mode)).elementType=t.elementType,n.type=t.type,n.stateNode=t.stateNode,n.alternate=t,t.alternate=n):(n.pendingProps=e,n.type=t.type,n.flags=0,n.subtreeFlags=0,n.deletions=null),n.flags=14680064&t.flags,n.childLanes=t.childLanes,n.lanes=t.lanes,n.child=t.child,n.memoizedProps=t.memoizedProps,n.memoizedState=t.memoizedState,n.updateQueue=t.updateQueue,e=t.dependencies,n.dependencies=null===e?null:{lanes:e.lanes,firstContext:e.firstContext},n.sibling=t.sibling,n.index=t.index,n.ref=t.ref,n}function fs(t,e,n,r,o,a){var s=2;if(r=t,"function"==typeof t)fu(t)&&(s=1);else if("string"==typeof t)s=5;else e:switch(t){case lr:return Wn(n.children,o,a,e);case Ei:s=8,o|=8;break;case bi:return(t=Nt(12,n,e,2|o)).elementType=bi,t.lanes=a,t;case _i:return(t=Nt(13,n,e,o)).elementType=_i,t.lanes=a,t;case vi:return(t=Nt(19,n,e,o)).elementType=vi,t.lanes=a,t;case Zc:return ms(n,o,a,e);default:if("object"==typeof t&&null!==t)switch(t.$$typeof){case zc:s=10;break e;case Gc:s=9;break e;case Ai:s=11;break e;case yi:s=14;break e;case pn:s=16,r=null;break e}throw Error(M(130,null==t?t:typeof t,""))}return(e=Nt(s,n,e,o)).elementType=t,e.type=r,e.lanes=a,e}function Wn(t,e,n,r){return(t=Nt(7,t,r,e)).lanes=n,t}function ms(t,e,n,r){return(t=Nt(22,t,r,e)).elementType=Zc,t.lanes=n,t.stateNode={isHidden:!1},t}function mu(t,e,n){return(t=Nt(6,t,null,e)).lanes=n,t}function gu(t,e,n){return(e=Nt(4,null!==t.children?t.children:[],t.key,e)).lanes=n,e.stateNode={containerInfo:t.containerInfo,pendingChildren:null,implementation:t.implementation},e}function DE(t,e,n,r,o){this.tag=e,this.containerInfo=t,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=Vi(0),this.expirationTimes=Vi(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=Vi(0),this.identifierPrefix=r,this.onRecoverableError=o,this.mutableSourceEagerHydrationData=null}function hu(t,e,n,r,o,a,s,i,l){return t=new DE(t,e,n,i,l),1===e?(e=1,!0===a&&(e|=8)):e=0,a=Nt(3,null,null,e),t.current=a,a.stateNode=t,a.memoizedState={element:r,isDehydrated:n,cache:null,transitions:null,pendingSuspenseBoundaries:null},xl(a),t}function U0(t){if(!t)return yn;e:{if(Fn(t=t._reactInternals)!==t||1!==t.tag)throw Error(M(170));var e=t;do{switch(e.tag){case 3:e=e.stateNode.context;break e;case 1:if(rt(e.type)){e=e.stateNode.__reactInternalMemoizedMergedChildContext;break e}}e=e.return}while(null!==e);throw Error(M(171))}if(1===t.tag){var n=t.type;if(rt(n))return pp(t,n,e)}return e}function q0(t,e,n,r,o,a,s,i,l){return(t=hu(n,r,!0,t,0,a,0,i,l)).context=U0(null),n=t.current,(a=sn(r=et(),o=xn(n))).callback=e??null,Sn(n,a,o),t.current.lanes=o,io(t,o,r),st(t,r),t}function gs(t,e,n,r){var o=e.current,a=et(),s=xn(o);return n=U0(n),null===e.context?e.context=n:e.pendingContext=n,(e=sn(a,s)).payload={element:t},null!==(r=void 0===r?null:r)&&(e.callback=r),null!==(t=Sn(o,e,s))&&(Ft(t,o,s,a),Ga(t,o,s)),s}function hs(t){return(t=t.current).child?(t.child.tag,t.child.stateNode):null}function H0(t,e){if(null!==(t=t.memoizedState)&&null!==t.dehydrated){var n=t.retryLane;t.retryLane=0!==n&&n"u"||"function"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(z0)}catch(t){console.error(t)}}(),Bc.exports=ct;var G0=Bc.exports;pi.createRoot=G0.createRoot,pi.hydrateRoot=G0.hydrateRoot;const Z0={embedId:null,baseApiUrl:null,prompt:null,model:null,temperature:null,showThoughts:!1,chatIcon:"plus",brandImageUrl:null,greeting:null,buttonColor:"#262626",userBgColor:"#2C2F35",assistantBgColor:"#2563eb",noSponsor:null,sponsorText:"Powered by AnythingLLM",sponsorLink:"https://anythingllm.com",position:"bottom-right",assistantName:"AnythingLLM Chat Assistant",assistantIcon:null,windowHeight:null,windowWidth:null,textSize:null,noHeader:null,language:"en",sendMessageText:null,resetChatText:null,openOnLoad:"off",supportEmail:null,username:null,defaultMessages:[]};const j0={_fallbacks:{defaultMessages:[]},defaultMessages:function(t=null){if("string"!=typeof t)return this._fallbacks.defaultMessages;try{const e=t.split(",");if(!Array.isArray(e)||0===e.length||!e.every((n=>"string"==typeof n&&n.length>0)))throw new Error("Invalid default-messages attribute value. Must be array of strings");return e.map((n=>n.trim()))}catch(e){return console.error("AnythingLLMEmbed",e),this._fallbacks.defaultMessages}}};function LE(t={}){const e={};for(let[n,r]of Object.entries(t)){if(!j0.hasOwnProperty(n)){e[n]=r;continue}const o=j0[n](r);e[n]=o}return e}let vs;const OE=new Uint8Array(16);function kE(){if(!vs&&(vs=typeof crypto<"u"&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto),!vs))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return vs(OE)}const Ve=[];for(let t=0;t<256;++t)Ve.push((t+256).toString(16).slice(1));const W0={randomUUID:typeof crypto<"u"&&crypto.randomUUID&&crypto.randomUUID.bind(crypto)};function Kn(t,e,n){if(W0.randomUUID&&!e&&!t)return W0.randomUUID();const r=(t=t||{}).random||(t.rng||kE)();if(r[6]=15&r[6]|64,r[8]=63&r[8]|128,e){n=n||0;for(let o=0;o<16;++o)e[n+o]=r[o];return e}return function(t,e=0){return Ve[t[e+0]]+Ve[t[e+1]]+Ve[t[e+2]]+Ve[t[e+3]]+"-"+Ve[t[e+4]]+Ve[t[e+5]]+"-"+Ve[t[e+6]]+Ve[t[e+7]]+"-"+Ve[t[e+8]]+Ve[t[e+9]]+"-"+Ve[t[e+10]]+Ve[t[e+11]]+Ve[t[e+12]]+Ve[t[e+13]]+Ve[t[e+14]]+Ve[t[e+15]]}(r)}function K0(){const[t,e]=U.useState("");return U.useEffect((()=>{!function(){var s,i;if(!window||null==(s=null==ae?void 0:ae.settings)||!s.embedId)return;const r=`allm_${null==(i=null==ae?void 0:ae.settings)?void 0:i.embedId}_session_id`,o=window.localStorage.getItem(r);if(o)return console.log("Resuming session id",o),void e(o);const a=Kn();console.log("Registering new session id",a),window.localStorage.setItem(r,a),e(a)}()}),[window]),t}const _u="___anythingllm-chat-widget-open___";const BE="\npre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*!\n Theme: GitHub Dark Dimmed\n Description: Dark dimmed theme as seen on github.com\n Author: github.com\n Maintainer: @Hirse\n Updated: 2021-05-15\n\n Colors taken from GitHub's CSS\n*/.hljs{color:#adbac7;background:#22272e}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#f47067}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#dcbdfb}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-variable{color:#6cb6ff}.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#96d0ff}.hljs-built_in,.hljs-symbol{color:#f69d50}.hljs-code,.hljs-comment,.hljs-formula{color:#768390}.hljs-name,.hljs-quote,.hljs-selector-pseudo,.hljs-selector-tag{color:#8ddb8c}.hljs-subst{color:#adbac7}.hljs-section{color:#316dca;font-weight:700}.hljs-bullet{color:#eac55f}.hljs-emphasis{color:#adbac7;font-style:italic}.hljs-strong{color:#adbac7;font-weight:700}.hljs-addition{color:#b4f1b4;background-color:#1b4721}.hljs-deletion{color:#ffd8d3;background-color:#78191b}\n",PE='\n /**\n * ==============================================\n * Dot Falling\n * ==============================================\n */\n .allm-dot-falling {\n position: relative;\n left: -9999px;\n width: 10px;\n height: 10px;\n border-radius: 5px;\n background-color: #000000;\n color: #5fa4fa;\n box-shadow: 9999px 0 0 0 #000000;\n animation: dot-falling 1.5s infinite linear;\n animation-delay: 0.1s;\n }\n\n .allm-dot-falling::before,\n .allm-dot-falling::after {\n content: "";\n display: inline-block;\n position: absolute;\n top: 0;\n }\n\n .allm-dot-falling::before {\n width: 10px;\n height: 10px;\n border-radius: 5px;\n background-color: #000000;\n color: #000000;\n animation: dot-falling-before 1.5s infinite linear;\n animation-delay: 0s;\n }\n\n .allm-dot-falling::after {\n width: 10px;\n height: 10px;\n border-radius: 5px;\n background-color: #000000;\n color: #000000;\n animation: dot-falling-after 1.5s infinite linear;\n animation-delay: 0.2s;\n }\n\n @keyframes dot-falling {\n 0% {\n box-shadow: 9999px -15px 0 0 rgba(152, 128, 255, 0);\n }\n 25%,\n 50%,\n 75% {\n box-shadow: 9999px 0 0 0 #000000;\n }\n 100% {\n box-shadow: 9999px 15px 0 0 rgba(152, 128, 255, 0);\n }\n }\n\n @keyframes dot-falling-before {\n 0% {\n box-shadow: 9984px -15px 0 0 rgba(152, 128, 255, 0);\n }\n 25%,\n 50%,\n 75% {\n box-shadow: 9984px 0 0 0 #000000;\n }\n 100% {\n box-shadow: 9984px 15px 0 0 rgba(152, 128, 255, 0);\n }\n }\n\n @keyframes dot-falling-after {\n 0% {\n box-shadow: 10014px -15px 0 0 rgba(152, 128, 255, 0);\n }\n 25%,\n 50%,\n 75% {\n box-shadow: 10014px 0 0 0 #000000;\n }\n 100% {\n box-shadow: 10014px 15px 0 0 rgba(152, 128, 255, 0);\n }\n }\n\n #chat-history::-webkit-scrollbar,\n #chat-container::-webkit-scrollbar,\n .allm-no-scroll::-webkit-scrollbar {\n display: none !important;\n }\n\n /* Hide scrollbar for IE, Edge and Firefox */\n #chat-history,\n #chat-container,\n .allm-no-scroll {\n -ms-overflow-style: none !important; /* IE and Edge */\n scrollbar-width: none !important; /* Firefox */\n }\n\n span.allm-whitespace-pre-line>p {\n margin: 0px;\n }\n';function UE(){return w.jsxs("head",{children:[w.jsx("style",{children:BE}),w.jsx("style",{children:PE}),w.jsx("link",{rel:"stylesheet",href:ae.stylesSrc})]})}const qE=U.createContext({color:"currentColor",size:"1em",weight:"regular",mirrored:!1});var HE=Object.defineProperty,ys=Object.getOwnPropertySymbols,Y0=Object.prototype.hasOwnProperty,X0=Object.prototype.propertyIsEnumerable,Q0=(t,e,n)=>e in t?HE(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n,J0=(t,e)=>{for(var n in e||(e={}))Y0.call(e,n)&&Q0(t,n,e[n]);if(ys)for(var n of ys(e))X0.call(e,n)&&Q0(t,n,e[n]);return t},ef=(t,e)=>{var n={};for(var r in t)Y0.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(null!=t&&ys)for(var r of ys(t))e.indexOf(r)<0&&X0.call(t,r)&&(n[r]=t[r]);return n};const Me=U.forwardRef(((t,e)=>{const n=t,{alt:r,color:o,size:a,weight:s,mirrored:i,children:l,weights:u}=n,c=ef(n,["alt","color","size","weight","mirrored","children","weights"]),p=U.useContext(qE),{color:d="currentColor",size:f,weight:b="regular",mirrored:A=!1}=p,y=ef(p,["color","size","weight","mirrored"]);return m.createElement("svg",J0(J0({ref:e,xmlns:"http://www.w3.org/2000/svg",width:a??f,height:a??f,fill:o??d,viewBox:"0 0 256 256",transform:i||A?"scale(-1, 1)":void 0},y),c),!!r&&m.createElement("title",null,r),l,u.get(s??b))}));Me.displayName="IconBase";const VE=new Map([["bold",m.createElement(m.Fragment,null,m.createElement("path",{d:"M228,128a100,100,0,0,1-98.66,100H128a99.39,99.39,0,0,1-68.62-27.29,12,12,0,0,1,16.48-17.45,76,76,0,1,0-1.57-109c-.13.13-.25.25-.39.37L54.89,92H72a12,12,0,0,1,0,24H24a12,12,0,0,1-12-12V56a12,12,0,0,1,24,0V76.72L57.48,57.06A100,100,0,0,1,228,128Z"}))],["duotone",m.createElement(m.Fragment,null,m.createElement("path",{d:"M72,104H24V56Z",opacity:"0.2"}),m.createElement("path",{d:"M195.88,60.08A96.08,96.08,0,0,0,60.25,60L49.31,70,29.66,50.3A8,8,0,0,0,16,56v48a8,8,0,0,0,8,8H72a8,8,0,0,0,5.66-13.66l-17-17,10.54-9.65a3.07,3.07,0,0,0,.26-.25,80,80,0,1,1,1.65,114.78,8,8,0,0,0-11,11.63A95.38,95.38,0,0,0,128,224h1.32A96,96,0,0,0,195.88,60.08ZM32,96V75.28L52.69,96Z"}))],["fill",m.createElement(m.Fragment,null,m.createElement("path",{d:"M224,128a96,96,0,0,1-94.71,96H128A95.38,95.38,0,0,1,62.1,197.8a8,8,0,0,1,11-11.63A80,80,0,1,0,71.43,71.39a3.07,3.07,0,0,1-.26.25L60.63,81.29l17,17A8,8,0,0,1,72,112H24a8,8,0,0,1-8-8V56A8,8,0,0,1,29.66,50.3L49.31,70,60.25,60A96,96,0,0,1,224,128Z"}))],["light",m.createElement(m.Fragment,null,m.createElement("path",{d:"M222,128a94,94,0,0,1-92.74,94H128a93.43,93.43,0,0,1-64.5-25.65,6,6,0,1,1,8.24-8.72A82,82,0,1,0,70,70l-.19.19L39.44,98H72a6,6,0,0,1,0,12H24a6,6,0,0,1-6-6V56a6,6,0,0,1,12,0V90.34L61.63,61.4A94,94,0,0,1,222,128Z"}))],["regular",m.createElement(m.Fragment,null,m.createElement("path",{d:"M224,128a96,96,0,0,1-94.71,96H128A95.38,95.38,0,0,1,62.1,197.8a8,8,0,0,1,11-11.63A80,80,0,1,0,71.43,71.39a3.07,3.07,0,0,1-.26.25L44.59,96H72a8,8,0,0,1,0,16H24a8,8,0,0,1-8-8V56a8,8,0,0,1,16,0V85.8L60.25,60A96,96,0,0,1,224,128Z"}))],["thin",m.createElement(m.Fragment,null,m.createElement("path",{d:"M220,128a92,92,0,0,1-90.77,92H128a91.47,91.47,0,0,1-63.13-25.1,4,4,0,1,1,5.5-5.82A84,84,0,1,0,68.6,68.57l-.13.12L34.3,100H72a4,4,0,0,1,0,8H24a4,4,0,0,1-4-4V56a4,4,0,0,1,8,0V94.89l35-32A92,92,0,0,1,220,128Z"}))]]);var $E=Object.defineProperty,zE=Object.defineProperties,GE=Object.getOwnPropertyDescriptors,tf=Object.getOwnPropertySymbols,ZE=Object.prototype.hasOwnProperty,jE=Object.prototype.propertyIsEnumerable,nf=(t,e,n)=>e in t?$E(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n;const rf=U.forwardRef(((t,e)=>m.createElement(Me,((t,e)=>zE(t,GE(e)))(((t,e)=>{for(var n in e||(e={}))ZE.call(e,n)&&nf(t,n,e[n]);if(tf)for(var n of tf(e))jE.call(e,n)&&nf(t,n,e[n]);return t})({ref:e},t),{weights:VE}))));rf.displayName="ArrowCounterClockwise";const YE=new Map([["bold",m.createElement(m.Fragment,null,m.createElement("path",{d:"M208.49,152.49l-72,72a12,12,0,0,1-17,0l-72-72a12,12,0,0,1,17-17L116,187V40a12,12,0,0,1,24,0V187l51.51-51.52a12,12,0,0,1,17,17Z"}))],["duotone",m.createElement(m.Fragment,null,m.createElement("path",{d:"M200,144l-72,72L56,144Z",opacity:"0.2"}),m.createElement("path",{d:"M207.39,140.94A8,8,0,0,0,200,136H136V40a8,8,0,0,0-16,0v96H56a8,8,0,0,0-5.66,13.66l72,72a8,8,0,0,0,11.32,0l72-72A8,8,0,0,0,207.39,140.94ZM128,204.69,75.31,152H180.69Z"}))],["fill",m.createElement(m.Fragment,null,m.createElement("path",{d:"M205.66,149.66l-72,72a8,8,0,0,1-11.32,0l-72-72A8,8,0,0,1,56,136h64V40a8,8,0,0,1,16,0v96h64a8,8,0,0,1,5.66,13.66Z"}))],["light",m.createElement(m.Fragment,null,m.createElement("path",{d:"M204.24,148.24l-72,72a6,6,0,0,1-8.48,0l-72-72a6,6,0,0,1,8.48-8.48L122,201.51V40a6,6,0,0,1,12,0V201.51l61.76-61.75a6,6,0,0,1,8.48,8.48Z"}))],["regular",m.createElement(m.Fragment,null,m.createElement("path",{d:"M205.66,149.66l-72,72a8,8,0,0,1-11.32,0l-72-72a8,8,0,0,1,11.32-11.32L120,196.69V40a8,8,0,0,1,16,0V196.69l58.34-58.35a8,8,0,0,1,11.32,11.32Z"}))],["thin",m.createElement(m.Fragment,null,m.createElement("path",{d:"M202.83,146.83l-72,72a4,4,0,0,1-5.66,0l-72-72a4,4,0,0,1,5.66-5.66L124,206.34V40a4,4,0,0,1,8,0V206.34l65.17-65.17a4,4,0,0,1,5.66,5.66Z"}))]]);var XE=Object.defineProperty,QE=Object.defineProperties,JE=Object.getOwnPropertyDescriptors,of=Object.getOwnPropertySymbols,eb=Object.prototype.hasOwnProperty,tb=Object.prototype.propertyIsEnumerable,af=(t,e,n)=>e in t?XE(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n;const sf=U.forwardRef(((t,e)=>m.createElement(Me,((t,e)=>QE(t,JE(e)))(((t,e)=>{for(var n in e||(e={}))eb.call(e,n)&&af(t,n,e[n]);if(of)for(var n of of(e))tb.call(e,n)&&af(t,n,e[n]);return t})({ref:e},t),{weights:YE}))));sf.displayName="ArrowDown";const ob=new Map([["bold",m.createElement(m.Fragment,null,m.createElement("path",{d:"M241,150.65s0,0,0-.05a51.33,51.33,0,0,0-2.53-5.9L196.93,50.18a12,12,0,0,0-2.5-3.65,36,36,0,0,0-50.92,0A12,12,0,0,0,140,55V76H116V55a12,12,0,0,0-3.51-8.48,36,36,0,0,0-50.92,0,12,12,0,0,0-2.5,3.65L17.53,144.7A51.33,51.33,0,0,0,15,150.6s0,0,0,.05A52,52,0,1,0,116,168V100h24v68a52,52,0,1,0,101-17.35ZM80,62.28a12,12,0,0,1,12-1.22v63.15a51.9,51.9,0,0,0-35.9-7.62ZM64,196a28,28,0,1,1,28-28A28,28,0,0,1,64,196ZM164,61.06a12.06,12.06,0,0,1,12,1.22l23.87,54.31a51.9,51.9,0,0,0-35.9,7.62ZM192,196a28,28,0,1,1,28-28A28,28,0,0,1,192,196Z"}))],["duotone",m.createElement(m.Fragment,null,m.createElement("path",{d:"M104,168a40,40,0,1,1-40-40A40,40,0,0,1,104,168Zm88-40a40,40,0,1,0,40,40A40,40,0,0,0,192,128Z",opacity:"0.2"}),m.createElement("path",{d:"M237.2,151.87v0a47.1,47.1,0,0,0-2.35-5.45L193.26,51.8a7.82,7.82,0,0,0-1.66-2.44,32,32,0,0,0-45.26,0A8,8,0,0,0,144,55V80H112V55a8,8,0,0,0-2.34-5.66,32,32,0,0,0-45.26,0,7.82,7.82,0,0,0-1.66,2.44L21.15,146.4a47.1,47.1,0,0,0-2.35,5.45v0A48,48,0,1,0,112,168V96h32v72a48,48,0,1,0,93.2-16.13ZM76.71,59.75a16,16,0,0,1,19.29-1v73.51a47.9,47.9,0,0,0-46.79-9.92ZM64,200a32,32,0,1,1,32-32A32,32,0,0,1,64,200ZM160,58.74a16,16,0,0,1,19.29,1l27.5,62.58A47.9,47.9,0,0,0,160,132.25ZM192,200a32,32,0,1,1,32-32A32,32,0,0,1,192,200Z"}))],["fill",m.createElement(m.Fragment,null,m.createElement("path",{d:"M237.22,151.9l0-.1a1.42,1.42,0,0,0-.07-.22,48.46,48.46,0,0,0-2.31-5.3L193.27,51.8a8,8,0,0,0-1.67-2.44,32,32,0,0,0-45.26,0A8,8,0,0,0,144,55V80H112V55a8,8,0,0,0-2.34-5.66,32,32,0,0,0-45.26,0,8,8,0,0,0-1.67,2.44L21.2,146.28a48.46,48.46,0,0,0-2.31,5.3,1.72,1.72,0,0,0-.07.21s0,.08,0,.11a48,48,0,0,0,90.32,32.51,47.49,47.49,0,0,0,2.9-16.59V96h32v71.83a47.49,47.49,0,0,0,2.9,16.59,48,48,0,0,0,90.32-32.51Zm-143.15,27a32,32,0,0,1-60.2-21.71l1.81-4.13A32,32,0,0,1,96,167.88V168h0A32,32,0,0,1,94.07,178.94ZM203,198.07A32,32,0,0,1,160,168h0v-.11a32,32,0,0,1,60.32-14.78l1.81,4.13A32,32,0,0,1,203,198.07Z"}))],["light",m.createElement(m.Fragment,null,m.createElement("path",{d:"M233,147.24,191.43,52.6a6,6,0,0,0-1.25-1.83,30,30,0,0,0-42.42,0A6,6,0,0,0,146,55V82H110V55a6,6,0,0,0-1.76-4.25,30,30,0,0,0-42.42,0,6,6,0,0,0-1.25,1.83L23,147.24A46,46,0,1,0,110,168V94h36v74a46,46,0,1,0,87-20.76ZM64,202a34,34,0,1,1,34-34A34,34,0,0,1,64,202Zm0-80a45.77,45.77,0,0,0-18.55,3.92L75.06,58.54A18,18,0,0,1,98,57.71V137A45.89,45.89,0,0,0,64,122Zm94-64.28a18,18,0,0,1,22.94.83l29.61,67.37A45.9,45.9,0,0,0,158,137ZM192,202a34,34,0,1,1,34-34A34,34,0,0,1,192,202Z"}))],["regular",m.createElement(m.Fragment,null,m.createElement("path",{d:"M237.2,151.87v0a47.1,47.1,0,0,0-2.35-5.45L193.26,51.8a7.82,7.82,0,0,0-1.66-2.44,32,32,0,0,0-45.26,0A8,8,0,0,0,144,55V80H112V55a8,8,0,0,0-2.34-5.66,32,32,0,0,0-45.26,0,7.82,7.82,0,0,0-1.66,2.44L21.15,146.4a47.1,47.1,0,0,0-2.35,5.45v0A48,48,0,1,0,112,168V96h32v72a48,48,0,1,0,93.2-16.13ZM76.71,59.75a16,16,0,0,1,19.29-1v73.51a47.9,47.9,0,0,0-46.79-9.92ZM64,200a32,32,0,1,1,32-32A32,32,0,0,1,64,200ZM160,58.74a16,16,0,0,1,19.29,1l27.5,62.58A47.9,47.9,0,0,0,160,132.25ZM192,200a32,32,0,1,1,32-32A32,32,0,0,1,192,200Z"}))],["thin",m.createElement(m.Fragment,null,m.createElement("path",{d:"M231.22,148.09,189.6,53.41a3.94,3.94,0,0,0-.83-1.22,28,28,0,0,0-39.6,0A4,4,0,0,0,148,55V84H108V55a4,4,0,0,0-1.17-2.83,28,28,0,0,0-39.6,0,3.94,3.94,0,0,0-.83,1.22L24.78,148.09A44,44,0,1,0,108,168V92h40v76a44,44,0,1,0,83.22-19.91ZM64,204a36,36,0,1,1,36-36A36,36,0,0,1,64,204Zm0-80a43.78,43.78,0,0,0-22.66,6.3L73.4,57.35a20,20,0,0,1,26.6-.59v86A44,44,0,0,0,64,124Zm92-67.23a20,20,0,0,1,26.6.59l32.06,72.94A43.92,43.92,0,0,0,156,142.74ZM192,204a36,36,0,1,1,36-36A36,36,0,0,1,192,204Z"}))]]);var ab=Object.defineProperty,sb=Object.defineProperties,ib=Object.getOwnPropertyDescriptors,lf=Object.getOwnPropertySymbols,lb=Object.prototype.hasOwnProperty,ub=Object.prototype.propertyIsEnumerable,uf=(t,e,n)=>e in t?ab(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n;const cf=U.forwardRef(((t,e)=>m.createElement(Me,((t,e)=>sb(t,ib(e)))(((t,e)=>{for(var n in e||(e={}))lb.call(e,n)&&uf(t,n,e[n]);if(lf)for(var n of lf(e))ub.call(e,n)&&uf(t,n,e[n]);return t})({ref:e},t),{weights:ob}))));cf.displayName="Binoculars";const pb=new Map([["bold",m.createElement(m.Fragment,null,m.createElement("path",{d:"M216.49,104.49l-80,80a12,12,0,0,1-17,0l-80-80a12,12,0,0,1,17-17L128,159l71.51-71.52a12,12,0,0,1,17,17Z"}))],["duotone",m.createElement(m.Fragment,null,m.createElement("path",{d:"M208,96l-80,80L48,96Z",opacity:"0.2"}),m.createElement("path",{d:"M215.39,92.94A8,8,0,0,0,208,88H48a8,8,0,0,0-5.66,13.66l80,80a8,8,0,0,0,11.32,0l80-80A8,8,0,0,0,215.39,92.94ZM128,164.69,67.31,104H188.69Z"}))],["fill",m.createElement(m.Fragment,null,m.createElement("path",{d:"M213.66,101.66l-80,80a8,8,0,0,1-11.32,0l-80-80A8,8,0,0,1,48,88H208a8,8,0,0,1,5.66,13.66Z"}))],["light",m.createElement(m.Fragment,null,m.createElement("path",{d:"M212.24,100.24l-80,80a6,6,0,0,1-8.48,0l-80-80a6,6,0,0,1,8.48-8.48L128,167.51l75.76-75.75a6,6,0,0,1,8.48,8.48Z"}))],["regular",m.createElement(m.Fragment,null,m.createElement("path",{d:"M213.66,101.66l-80,80a8,8,0,0,1-11.32,0l-80-80A8,8,0,0,1,53.66,90.34L128,164.69l74.34-74.35a8,8,0,0,1,11.32,11.32Z"}))],["thin",m.createElement(m.Fragment,null,m.createElement("path",{d:"M210.83,98.83l-80,80a4,4,0,0,1-5.66,0l-80-80a4,4,0,0,1,5.66-5.66L128,170.34l77.17-77.17a4,4,0,1,1,5.66,5.66Z"}))]]);var fb=Object.defineProperty,mb=Object.defineProperties,gb=Object.getOwnPropertyDescriptors,df=Object.getOwnPropertySymbols,hb=Object.prototype.hasOwnProperty,Eb=Object.prototype.propertyIsEnumerable,pf=(t,e,n)=>e in t?fb(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n;const vu=U.forwardRef(((t,e)=>m.createElement(Me,((t,e)=>mb(t,gb(e)))(((t,e)=>{for(var n in e||(e={}))hb.call(e,n)&&pf(t,n,e[n]);if(df)for(var n of df(e))Eb.call(e,n)&&pf(t,n,e[n]);return t})({ref:e},t),{weights:pb}))));vu.displayName="CaretDown";const _b=new Map([["bold",m.createElement(m.Fragment,null,m.createElement("path",{d:"M120,128a16,16,0,1,1-16-16A16,16,0,0,1,120,128Zm32-16a16,16,0,1,0,16,16A16,16,0,0,0,152,112Zm84,16A108,108,0,0,1,78.77,224.15L46.34,235A20,20,0,0,1,21,209.66l10.81-32.43A108,108,0,1,1,236,128Zm-24,0A84,84,0,1,0,55.27,170.06a12,12,0,0,1,1,9.81l-9.93,29.79,29.79-9.93a12.1,12.1,0,0,1,3.8-.62,12,12,0,0,1,6,1.62A84,84,0,0,0,212,128Z"}))],["duotone",m.createElement(m.Fragment,null,m.createElement("path",{d:"M224,128A96,96,0,0,1,79.93,211.11h0L42.54,223.58a8,8,0,0,1-10.12-10.12l12.47-37.39h0A96,96,0,1,1,224,128Z",opacity:"0.2"}),m.createElement("path",{d:"M128,24A104,104,0,0,0,36.18,176.88L24.83,210.93a16,16,0,0,0,20.24,20.24l34.05-11.35A104,104,0,1,0,128,24Zm0,192a87.87,87.87,0,0,1-44.06-11.81,8,8,0,0,0-4-1.08,7.85,7.85,0,0,0-2.53.42L40,216,52.47,178.6a8,8,0,0,0-.66-6.54A88,88,0,1,1,128,216Zm12-88a12,12,0,1,1-12-12A12,12,0,0,1,140,128Zm-44,0a12,12,0,1,1-12-12A12,12,0,0,1,96,128Zm88,0a12,12,0,1,1-12-12A12,12,0,0,1,184,128Z"}))],["fill",m.createElement(m.Fragment,null,m.createElement("path",{d:"M128,24A104,104,0,0,0,36.18,176.88L24.83,210.93a16,16,0,0,0,20.24,20.24l34.05-11.35A104,104,0,1,0,128,24ZM84,140a12,12,0,1,1,12-12A12,12,0,0,1,84,140Zm44,0a12,12,0,1,1,12-12A12,12,0,0,1,128,140Zm44,0a12,12,0,1,1,12-12A12,12,0,0,1,172,140Z"}))],["light",m.createElement(m.Fragment,null,m.createElement("path",{d:"M138,128a10,10,0,1,1-10-10A10,10,0,0,1,138,128ZM84,118a10,10,0,1,0,10,10A10,10,0,0,0,84,118Zm88,0a10,10,0,1,0,10,10A10,10,0,0,0,172,118Zm58,10A102,102,0,0,1,79.31,217.65L44.44,229.27a14,14,0,0,1-17.71-17.71l11.62-34.87A102,102,0,1,1,230,128Zm-12,0A90,90,0,1,0,50.08,173.06a6,6,0,0,1,.5,4.91L38.12,215.35a2,2,0,0,0,2.53,2.53L78,205.42a6.2,6.2,0,0,1,1.9-.31,6.09,6.09,0,0,1,3,.81A90,90,0,0,0,218,128Z"}))],["regular",m.createElement(m.Fragment,null,m.createElement("path",{d:"M140,128a12,12,0,1,1-12-12A12,12,0,0,1,140,128ZM84,116a12,12,0,1,0,12,12A12,12,0,0,0,84,116Zm88,0a12,12,0,1,0,12,12A12,12,0,0,0,172,116Zm60,12A104,104,0,0,1,79.12,219.82L45.07,231.17a16,16,0,0,1-20.24-20.24l11.35-34.05A104,104,0,1,1,232,128Zm-16,0A88,88,0,1,0,51.81,172.06a8,8,0,0,1,.66,6.54L40,216,77.4,203.53a7.85,7.85,0,0,1,2.53-.42,8,8,0,0,1,4,1.08A88,88,0,0,0,216,128Z"}))],["thin",m.createElement(m.Fragment,null,m.createElement("path",{d:"M136,128a8,8,0,1,1-8-8A8,8,0,0,1,136,128Zm-52-8a8,8,0,1,0,8,8A8,8,0,0,0,84,120Zm88,0a8,8,0,1,0,8,8A8,8,0,0,0,172,120Zm56,8A100,100,0,0,1,79.5,215.47l-35.69,11.9a12,12,0,0,1-15.18-15.18l11.9-35.69A100,100,0,1,1,228,128Zm-8,0A92,92,0,1,0,48.35,174.07a4,4,0,0,1,.33,3.27L36.22,214.72a4,4,0,0,0,5.06,5.06l37.38-12.46a3.93,3.93,0,0,1,1.27-.21,4.05,4.05,0,0,1,2,.54A92,92,0,0,0,220,128Z"}))]]);var vb=Object.defineProperty,yb=Object.defineProperties,Db=Object.getOwnPropertyDescriptors,ff=Object.getOwnPropertySymbols,Cb=Object.prototype.hasOwnProperty,Sb=Object.prototype.propertyIsEnumerable,mf=(t,e,n)=>e in t?vb(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n;const gf=U.forwardRef(((t,e)=>m.createElement(Me,((t,e)=>yb(t,Db(e)))(((t,e)=>{for(var n in e||(e={}))Cb.call(e,n)&&mf(t,n,e[n]);if(ff)for(var n of ff(e))Sb.call(e,n)&&mf(t,n,e[n]);return t})({ref:e},t),{weights:_b}))));gf.displayName="ChatCircleDots";const wb=new Map([["bold",m.createElement(m.Fragment,null,m.createElement("path",{d:"M232.49,80.49l-128,128a12,12,0,0,1-17,0l-56-56a12,12,0,1,1,17-17L96,183,215.51,63.51a12,12,0,0,1,17,17Z"}))],["duotone",m.createElement(m.Fragment,null,m.createElement("path",{d:"M232,56V200a16,16,0,0,1-16,16H40a16,16,0,0,1-16-16V56A16,16,0,0,1,40,40H216A16,16,0,0,1,232,56Z",opacity:"0.2"}),m.createElement("path",{d:"M205.66,85.66l-96,96a8,8,0,0,1-11.32,0l-40-40a8,8,0,0,1,11.32-11.32L104,164.69l90.34-90.35a8,8,0,0,1,11.32,11.32Z"}))],["fill",m.createElement(m.Fragment,null,m.createElement("path",{d:"M216,40H40A16,16,0,0,0,24,56V200a16,16,0,0,0,16,16H216a16,16,0,0,0,16-16V56A16,16,0,0,0,216,40ZM205.66,85.66l-96,96a8,8,0,0,1-11.32,0l-40-40a8,8,0,0,1,11.32-11.32L104,164.69l90.34-90.35a8,8,0,0,1,11.32,11.32Z"}))],["light",m.createElement(m.Fragment,null,m.createElement("path",{d:"M228.24,76.24l-128,128a6,6,0,0,1-8.48,0l-56-56a6,6,0,0,1,8.48-8.48L96,191.51,219.76,67.76a6,6,0,0,1,8.48,8.48Z"}))],["regular",m.createElement(m.Fragment,null,m.createElement("path",{d:"M229.66,77.66l-128,128a8,8,0,0,1-11.32,0l-56-56a8,8,0,0,1,11.32-11.32L96,188.69,218.34,66.34a8,8,0,0,1,11.32,11.32Z"}))],["thin",m.createElement(m.Fragment,null,m.createElement("path",{d:"M226.83,74.83l-128,128a4,4,0,0,1-5.66,0l-56-56a4,4,0,0,1,5.66-5.66L96,194.34,221.17,69.17a4,4,0,1,1,5.66,5.66Z"}))]]);var xb=Object.defineProperty,Rb=Object.defineProperties,Lb=Object.getOwnPropertyDescriptors,hf=Object.getOwnPropertySymbols,Ob=Object.prototype.hasOwnProperty,kb=Object.prototype.propertyIsEnumerable,Ef=(t,e,n)=>e in t?xb(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n;const bf=U.forwardRef(((t,e)=>m.createElement(Me,((t,e)=>Rb(t,Lb(e)))(((t,e)=>{for(var n in e||(e={}))Ob.call(e,n)&&Ef(t,n,e[n]);if(hf)for(var n of hf(e))kb.call(e,n)&&Ef(t,n,e[n]);return t})({ref:e},t),{weights:wb}))));bf.displayName="Check";const Fb=new Map([["bold",m.createElement(m.Fragment,null,m.createElement("path",{d:"M236,128a108,108,0,0,1-216,0c0-42.52,24.73-81.34,63-98.9A12,12,0,1,1,93,50.91C63.24,64.57,44,94.83,44,128a84,84,0,0,0,168,0c0-33.17-19.24-63.43-49-77.09A12,12,0,1,1,173,29.1C211.27,46.66,236,85.48,236,128Z"}))],["duotone",m.createElement(m.Fragment,null,m.createElement("path",{d:"M224,128a96,96,0,1,1-96-96A96,96,0,0,1,224,128Z",opacity:"0.2"}),m.createElement("path",{d:"M232,128a104,104,0,0,1-208,0c0-41,23.81-78.36,60.66-95.27a8,8,0,0,1,6.68,14.54C60.15,61.59,40,93.27,40,128a88,88,0,0,0,176,0c0-34.73-20.15-66.41-51.34-80.73a8,8,0,0,1,6.68-14.54C208.19,49.64,232,87,232,128Z"}))],["fill",m.createElement(m.Fragment,null,m.createElement("path",{d:"M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,176A72,72,0,0,1,92,65.64a8,8,0,0,1,8,13.85,56,56,0,1,0,56,0,8,8,0,0,1,8-13.85A72,72,0,0,1,128,200Z"}))],["light",m.createElement(m.Fragment,null,m.createElement("path",{d:"M230,128a102,102,0,0,1-204,0c0-40.18,23.35-76.86,59.5-93.45a6,6,0,0,1,5,10.9C58.61,60.09,38,92.49,38,128a90,90,0,0,0,180,0c0-35.51-20.61-67.91-52.5-82.55a6,6,0,0,1,5-10.9C206.65,51.14,230,87.82,230,128Z"}))],["regular",m.createElement(m.Fragment,null,m.createElement("path",{d:"M232,128a104,104,0,0,1-208,0c0-41,23.81-78.36,60.66-95.27a8,8,0,0,1,6.68,14.54C60.15,61.59,40,93.27,40,128a88,88,0,0,0,176,0c0-34.73-20.15-66.41-51.34-80.73a8,8,0,0,1,6.68-14.54C208.19,49.64,232,87,232,128Z"}))],["thin",m.createElement(m.Fragment,null,m.createElement("path",{d:"M228,128a100,100,0,0,1-200,0c0-39.4,22.9-75.37,58.33-91.63a4,4,0,1,1,3.34,7.27C57.07,58.6,36,91.71,36,128a92,92,0,0,0,184,0c0-36.29-21.07-69.4-53.67-84.36a4,4,0,1,1,3.34-7.27C205.1,52.63,228,88.6,228,128Z"}))]]);var Bb=Object.defineProperty,Pb=Object.defineProperties,Ub=Object.getOwnPropertyDescriptors,Af=Object.getOwnPropertySymbols,qb=Object.prototype.hasOwnProperty,Hb=Object.prototype.propertyIsEnumerable,_f=(t,e,n)=>e in t?Bb(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n;const Ds=U.forwardRef(((t,e)=>m.createElement(Me,((t,e)=>Pb(t,Ub(e)))(((t,e)=>{for(var n in e||(e={}))qb.call(e,n)&&_f(t,n,e[n]);if(Af)for(var n of Af(e))Hb.call(e,n)&&_f(t,n,e[n]);return t})({ref:e},t),{weights:Fb}))));Ds.displayName="CircleNotch";const zb=new Map([["bold",m.createElement(m.Fragment,null,m.createElement("path",{d:"M216,28H88A12,12,0,0,0,76,40V76H40A12,12,0,0,0,28,88V216a12,12,0,0,0,12,12H168a12,12,0,0,0,12-12V180h36a12,12,0,0,0,12-12V40A12,12,0,0,0,216,28ZM156,204H52V100H156Zm48-48H180V88a12,12,0,0,0-12-12H100V52H204Z"}))],["duotone",m.createElement(m.Fragment,null,m.createElement("path",{d:"M216,40V168H168V88H88V40Z",opacity:"0.2"}),m.createElement("path",{d:"M216,32H88a8,8,0,0,0-8,8V80H40a8,8,0,0,0-8,8V216a8,8,0,0,0,8,8H168a8,8,0,0,0,8-8V176h40a8,8,0,0,0,8-8V40A8,8,0,0,0,216,32ZM160,208H48V96H160Zm48-48H176V88a8,8,0,0,0-8-8H96V48H208Z"}))],["fill",m.createElement(m.Fragment,null,m.createElement("path",{d:"M216,32H88a8,8,0,0,0-8,8V80H40a8,8,0,0,0-8,8V216a8,8,0,0,0,8,8H168a8,8,0,0,0,8-8V176h40a8,8,0,0,0,8-8V40A8,8,0,0,0,216,32Zm-8,128H176V88a8,8,0,0,0-8-8H96V48H208Z"}))],["light",m.createElement(m.Fragment,null,m.createElement("path",{d:"M216,34H88a6,6,0,0,0-6,6V82H40a6,6,0,0,0-6,6V216a6,6,0,0,0,6,6H168a6,6,0,0,0,6-6V174h42a6,6,0,0,0,6-6V40A6,6,0,0,0,216,34ZM162,210H46V94H162Zm48-48H174V88a6,6,0,0,0-6-6H94V46H210Z"}))],["regular",m.createElement(m.Fragment,null,m.createElement("path",{d:"M216,32H88a8,8,0,0,0-8,8V80H40a8,8,0,0,0-8,8V216a8,8,0,0,0,8,8H168a8,8,0,0,0,8-8V176h40a8,8,0,0,0,8-8V40A8,8,0,0,0,216,32ZM160,208H48V96H160Zm48-48H176V88a8,8,0,0,0-8-8H96V48H208Z"}))],["thin",m.createElement(m.Fragment,null,m.createElement("path",{d:"M216,36H88a4,4,0,0,0-4,4V84H40a4,4,0,0,0-4,4V216a4,4,0,0,0,4,4H168a4,4,0,0,0,4-4V172h44a4,4,0,0,0,4-4V40A4,4,0,0,0,216,36ZM164,212H44V92H164Zm48-48H172V88a4,4,0,0,0-4-4H92V44H212Z"}))]]);var Gb=Object.defineProperty,Zb=Object.defineProperties,jb=Object.getOwnPropertyDescriptors,vf=Object.getOwnPropertySymbols,Wb=Object.prototype.hasOwnProperty,Kb=Object.prototype.propertyIsEnumerable,yf=(t,e,n)=>e in t?Gb(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n;const Df=U.forwardRef(((t,e)=>m.createElement(Me,((t,e)=>Zb(t,jb(e)))(((t,e)=>{for(var n in e||(e={}))Wb.call(e,n)&&yf(t,n,e[n]);if(vf)for(var n of vf(e))Kb.call(e,n)&&yf(t,n,e[n]);return t})({ref:e},t),{weights:zb}))));Df.displayName="Copy";const Qb=new Map([["bold",m.createElement(m.Fragment,null,m.createElement("path",{d:"M128,96a32,32,0,1,0,32,32A32,32,0,0,0,128,96Zm0,40a8,8,0,1,1,8-8A8,8,0,0,1,128,136Zm0-56A32,32,0,1,0,96,48,32,32,0,0,0,128,80Zm0-40a8,8,0,1,1-8,8A8,8,0,0,1,128,40Zm0,136a32,32,0,1,0,32,32A32,32,0,0,0,128,176Zm0,40a8,8,0,1,1,8-8A8,8,0,0,1,128,216Z"}))],["duotone",m.createElement(m.Fragment,null,m.createElement("path",{d:"M152,128a24,24,0,1,1-24-24A24,24,0,0,1,152,128ZM128,72a24,24,0,1,0-24-24A24,24,0,0,0,128,72Zm0,112a24,24,0,1,0,24,24A24,24,0,0,0,128,184Z",opacity:"0.2"}),m.createElement("path",{d:"M128,96a32,32,0,1,0,32,32A32,32,0,0,0,128,96Zm0,48a16,16,0,1,1,16-16A16,16,0,0,1,128,144Zm0-64A32,32,0,1,0,96,48,32,32,0,0,0,128,80Zm0-48a16,16,0,1,1-16,16A16,16,0,0,1,128,32Zm0,144a32,32,0,1,0,32,32A32,32,0,0,0,128,176Zm0,48a16,16,0,1,1,16-16A16,16,0,0,1,128,224Z"}))],["fill",m.createElement(m.Fragment,null,m.createElement("path",{d:"M156,128a28,28,0,1,1-28-28A28,28,0,0,1,156,128ZM128,76a28,28,0,1,0-28-28A28,28,0,0,0,128,76Zm0,104a28,28,0,1,0,28,28A28,28,0,0,0,128,180Z"}))],["light",m.createElement(m.Fragment,null,m.createElement("path",{d:"M128,98a30,30,0,1,0,30,30A30,30,0,0,0,128,98Zm0,48a18,18,0,1,1,18-18A18,18,0,0,1,128,146Zm0-68A30,30,0,1,0,98,48,30,30,0,0,0,128,78Zm0-48a18,18,0,1,1-18,18A18,18,0,0,1,128,30Zm0,148a30,30,0,1,0,30,30A30,30,0,0,0,128,178Zm0,48a18,18,0,1,1,18-18A18,18,0,0,1,128,226Z"}))],["regular",m.createElement(m.Fragment,null,m.createElement("path",{d:"M128,96a32,32,0,1,0,32,32A32,32,0,0,0,128,96Zm0,48a16,16,0,1,1,16-16A16,16,0,0,1,128,144Zm0-64A32,32,0,1,0,96,48,32,32,0,0,0,128,80Zm0-48a16,16,0,1,1-16,16A16,16,0,0,1,128,32Zm0,144a32,32,0,1,0,32,32A32,32,0,0,0,128,176Zm0,48a16,16,0,1,1,16-16A16,16,0,0,1,128,224Z"}))],["thin",m.createElement(m.Fragment,null,m.createElement("path",{d:"M128,100a28,28,0,1,0,28,28A28,28,0,0,0,128,100Zm0,48a20,20,0,1,1,20-20A20,20,0,0,1,128,148Zm0-72a28,28,0,1,0-28-28A28,28,0,0,0,128,76Zm0-48a20,20,0,1,1-20,20A20,20,0,0,1,128,28Zm0,152a28,28,0,1,0,28,28A28,28,0,0,0,128,180Zm0,48a20,20,0,1,1,20-20A20,20,0,0,1,128,228Z"}))]]);var Jb=Object.defineProperty,eA=Object.defineProperties,tA=Object.getOwnPropertyDescriptors,Cf=Object.getOwnPropertySymbols,nA=Object.prototype.hasOwnProperty,rA=Object.prototype.propertyIsEnumerable,Sf=(t,e,n)=>e in t?Jb(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n;const Nf=U.forwardRef(((t,e)=>m.createElement(Me,((t,e)=>eA(t,tA(e)))(((t,e)=>{for(var n in e||(e={}))nA.call(e,n)&&Sf(t,n,e[n]);if(Cf)for(var n of Cf(e))rA.call(e,n)&&Sf(t,n,e[n]);return t})({ref:e},t),{weights:Qb}))));Nf.displayName="DotsThreeOutlineVertical";const sA=new Map([["bold",m.createElement(m.Fragment,null,m.createElement("path",{d:"M224,44H32A12,12,0,0,0,20,56V192a20,20,0,0,0,20,20H216a20,20,0,0,0,20-20V56A12,12,0,0,0,224,44Zm-96,83.72L62.85,68h130.3ZM92.79,128,44,172.72V83.28Zm17.76,16.28,9.34,8.57a12,12,0,0,0,16.22,0l9.34-8.57L193.15,188H62.85ZM163.21,128,212,83.28v89.44Z"}))],["duotone",m.createElement(m.Fragment,null,m.createElement("path",{d:"M224,56l-96,88L32,56Z",opacity:"0.2"}),m.createElement("path",{d:"M224,48H32a8,8,0,0,0-8,8V192a16,16,0,0,0,16,16H216a16,16,0,0,0,16-16V56A8,8,0,0,0,224,48Zm-96,85.15L52.57,64H203.43ZM98.71,128,40,181.81V74.19Zm11.84,10.85,12,11.05a8,8,0,0,0,10.82,0l12-11.05,58,53.15H52.57ZM157.29,128,216,74.18V181.82Z"}))],["fill",m.createElement(m.Fragment,null,m.createElement("path",{d:"M224,48H32a8,8,0,0,0-8,8V192a16,16,0,0,0,16,16H216a16,16,0,0,0,16-16V56A8,8,0,0,0,224,48ZM98.71,128,40,181.81V74.19Zm11.84,10.85,12,11.05a8,8,0,0,0,10.82,0l12-11.05,58,53.15H52.57ZM157.29,128,216,74.18V181.82Z"}))],["light",m.createElement(m.Fragment,null,m.createElement("path",{d:"M224,50H32a6,6,0,0,0-6,6V192a14,14,0,0,0,14,14H216a14,14,0,0,0,14-14V56A6,6,0,0,0,224,50Zm-96,85.86L47.42,62H208.58ZM101.67,128,38,186.36V69.64Zm8.88,8.14L124,148.42a6,6,0,0,0,8.1,0l13.4-12.28L208.58,194H47.43ZM154.33,128,218,69.64V186.36Z"}))],["regular",m.createElement(m.Fragment,null,m.createElement("path",{d:"M224,48H32a8,8,0,0,0-8,8V192a16,16,0,0,0,16,16H216a16,16,0,0,0,16-16V56A8,8,0,0,0,224,48Zm-96,85.15L52.57,64H203.43ZM98.71,128,40,181.81V74.19Zm11.84,10.85,12,11.05a8,8,0,0,0,10.82,0l12-11.05,58,53.15H52.57ZM157.29,128,216,74.18V181.82Z"}))],["thin",m.createElement(m.Fragment,null,m.createElement("path",{d:"M224,52H32a4,4,0,0,0-4,4V192a12,12,0,0,0,12,12H216a12,12,0,0,0,12-12V56A4,4,0,0,0,224,52Zm-96,86.57L42.28,60H213.72ZM104.63,128,36,190.91V65.09Zm5.92,5.43L125.3,147a4,4,0,0,0,5.4,0l14.75-13.52L213.72,196H42.28ZM151.37,128,220,65.09V190.91Z"}))]]);var iA=Object.defineProperty,lA=Object.defineProperties,uA=Object.getOwnPropertyDescriptors,Tf=Object.getOwnPropertySymbols,cA=Object.prototype.hasOwnProperty,dA=Object.prototype.propertyIsEnumerable,wf=(t,e,n)=>e in t?iA(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n;const xf=U.forwardRef(((t,e)=>m.createElement(Me,((t,e)=>lA(t,uA(e)))(((t,e)=>{for(var n in e||(e={}))cA.call(e,n)&&wf(t,n,e[n]);if(Tf)for(var n of Tf(e))dA.call(e,n)&&wf(t,n,e[n]);return t})({ref:e},t),{weights:sA}))));xf.displayName="Envelope";const mA=new Map([["bold",m.createElement(m.Fragment,null,m.createElement("path",{d:"M204.73,51.85A108.07,108.07,0,0,0,20,128v56a28,28,0,0,0,28,28H64a28,28,0,0,0,28-28V144a28,28,0,0,0-28-28H44.84A84.05,84.05,0,0,1,128,44h.64a83.7,83.7,0,0,1,82.52,72H192a28,28,0,0,0-28,28v40a28,28,0,0,0,28,28h19.6A20,20,0,0,1,192,228H136a12,12,0,0,0,0,24h56a44.05,44.05,0,0,0,44-44V128A107.34,107.34,0,0,0,204.73,51.85ZM64,140a4,4,0,0,1,4,4v40a4,4,0,0,1-4,4H48a4,4,0,0,1-4-4V140Zm124,44V144a4,4,0,0,1,4-4h20v48H192A4,4,0,0,1,188,184Z"}))],["duotone",m.createElement(m.Fragment,null,m.createElement("path",{d:"M80,144v40a16,16,0,0,1-16,16H48a16,16,0,0,1-16-16V128H64A16,16,0,0,1,80,144Zm112-16a16,16,0,0,0-16,16v40a16,16,0,0,0,16,16h32V128Z",opacity:"0.2"}),m.createElement("path",{d:"M201.89,54.66A104.08,104.08,0,0,0,24,128v56a24,24,0,0,0,24,24H64a24,24,0,0,0,24-24V144a24,24,0,0,0-24-24H40.36A88.12,88.12,0,0,1,190.54,65.93,87.39,87.39,0,0,1,215.65,120H192a24,24,0,0,0-24,24v40a24,24,0,0,0,24,24h24a24,24,0,0,1-24,24H136a8,8,0,0,0,0,16h56a40,40,0,0,0,40-40V128A103.41,103.41,0,0,0,201.89,54.66ZM64,136a8,8,0,0,1,8,8v40a8,8,0,0,1-8,8H48a8,8,0,0,1-8-8V136Zm128,56a8,8,0,0,1-8-8V144a8,8,0,0,1,8-8h24v56Z"}))],["fill",m.createElement(m.Fragment,null,m.createElement("path",{d:"M232,128v80a40,40,0,0,1-40,40H136a8,8,0,0,1,0-16h56a24,24,0,0,0,24-24H192a24,24,0,0,1-24-24V144a24,24,0,0,1,24-24h23.65A88,88,0,0,0,66,65.54,87.29,87.29,0,0,0,40.36,120H64a24,24,0,0,1,24,24v40a24,24,0,0,1-24,24H48a24,24,0,0,1-24-24V128A104.11,104.11,0,0,1,201.89,54.66,103.41,103.41,0,0,1,232,128Z"}))],["light",m.createElement(m.Fragment,null,m.createElement("path",{d:"M200.47,56.07A101.37,101.37,0,0,0,128.77,26H128A102,102,0,0,0,26,128v56a22,22,0,0,0,22,22H64a22,22,0,0,0,22-22V144a22,22,0,0,0-22-22H38.2A90,90,0,0,1,128,38h.68a89.71,89.71,0,0,1,89.13,84H192a22,22,0,0,0-22,22v40a22,22,0,0,0,22,22h26v2a26,26,0,0,1-26,26H136a6,6,0,0,0,0,12h56a38,38,0,0,0,38-38V128A101.44,101.44,0,0,0,200.47,56.07ZM64,134a10,10,0,0,1,10,10v40a10,10,0,0,1-10,10H48a10,10,0,0,1-10-10V134Zm118,50V144a10,10,0,0,1,10-10h26v60H192A10,10,0,0,1,182,184Z"}))],["regular",m.createElement(m.Fragment,null,m.createElement("path",{d:"M201.89,54.66A103.43,103.43,0,0,0,128.79,24H128A104,104,0,0,0,24,128v56a24,24,0,0,0,24,24H64a24,24,0,0,0,24-24V144a24,24,0,0,0-24-24H40.36A88.12,88.12,0,0,1,190.54,65.93,87.39,87.39,0,0,1,215.65,120H192a24,24,0,0,0-24,24v40a24,24,0,0,0,24,24h24a24,24,0,0,1-24,24H136a8,8,0,0,0,0,16h56a40,40,0,0,0,40-40V128A103.41,103.41,0,0,0,201.89,54.66ZM64,136a8,8,0,0,1,8,8v40a8,8,0,0,1-8,8H48a8,8,0,0,1-8-8V136Zm128,56a8,8,0,0,1-8-8V144a8,8,0,0,1,8-8h24v56Z"}))],["thin",m.createElement(m.Fragment,null,m.createElement("path",{d:"M199.05,57.48A100.07,100.07,0,0,0,28,128v56a20,20,0,0,0,20,20H64a20,20,0,0,0,20-20V144a20,20,0,0,0-20-20H36.08A92,92,0,0,1,128,36h.7a91.75,91.75,0,0,1,91.22,88H192a20,20,0,0,0-20,20v40a20,20,0,0,0,20,20h28v4a28,28,0,0,1-28,28H136a4,4,0,0,0,0,8h56a36,36,0,0,0,36-36V128A99.44,99.44,0,0,0,199.05,57.48ZM64,132a12,12,0,0,1,12,12v40a12,12,0,0,1-12,12H48a12,12,0,0,1-12-12V132Zm116,52V144a12,12,0,0,1,12-12h28v64H192A12,12,0,0,1,180,184Z"}))]]);var gA=Object.defineProperty,hA=Object.defineProperties,EA=Object.getOwnPropertyDescriptors,Rf=Object.getOwnPropertySymbols,bA=Object.prototype.hasOwnProperty,AA=Object.prototype.propertyIsEnumerable,Lf=(t,e,n)=>e in t?gA(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n;const Of=U.forwardRef(((t,e)=>m.createElement(Me,((t,e)=>hA(t,EA(e)))(((t,e)=>{for(var n in e||(e={}))bA.call(e,n)&&Lf(t,n,e[n]);if(Rf)for(var n of Rf(e))AA.call(e,n)&&Lf(t,n,e[n]);return t})({ref:e},t),{weights:mA}))));Of.displayName="Headset";const yA=new Map([["bold",m.createElement(m.Fragment,null,m.createElement("path",{d:"M252,152a12,12,0,0,1-12,12H228v12a12,12,0,0,1-24,0V164H192a12,12,0,0,1,0-24h12V128a12,12,0,0,1,24,0v12h12A12,12,0,0,1,252,152ZM56,76H68V88a12,12,0,0,0,24,0V76h12a12,12,0,1,0,0-24H92V40a12,12,0,0,0-24,0V52H56a12,12,0,0,0,0,24ZM184,188h-4v-4a12,12,0,0,0-24,0v4h-4a12,12,0,0,0,0,24h4v4a12,12,0,0,0,24,0v-4h4a12,12,0,0,0,0-24ZM222.14,82.83,82.82,222.14a20,20,0,0,1-28.28,0L33.85,201.46a20,20,0,0,1,0-28.29L173.17,33.86a20,20,0,0,1,28.28,0l20.69,20.68A20,20,0,0,1,222.14,82.83ZM159,112,144,97,53.65,187.31l15,15Zm43.31-43.31-15-15L161,80l15,15Z"}))],["duotone",m.createElement(m.Fragment,null,m.createElement("path",{d:"M176,112,74.34,213.66a8,8,0,0,1-11.31,0L42.34,193a8,8,0,0,1,0-11.31L144,80Z",opacity:"0.2"}),m.createElement("path",{d:"M248,152a8,8,0,0,1-8,8H224v16a8,8,0,0,1-16,0V160H192a8,8,0,0,1,0-16h16V128a8,8,0,0,1,16,0v16h16A8,8,0,0,1,248,152ZM56,72H72V88a8,8,0,0,0,16,0V72h16a8,8,0,0,0,0-16H88V40a8,8,0,0,0-16,0V56H56a8,8,0,0,0,0,16ZM184,192h-8v-8a8,8,0,0,0-16,0v8h-8a8,8,0,0,0,0,16h8v8a8,8,0,0,0,16,0v-8h8a8,8,0,0,0,0-16ZM219.31,80,80,219.31a16,16,0,0,1-22.62,0L36.68,198.63a16,16,0,0,1,0-22.63L176,36.69a16,16,0,0,1,22.63,0l20.68,20.68A16,16,0,0,1,219.31,80Zm-54.63,32L144,91.31l-96,96L68.68,208ZM208,68.69,187.31,48l-32,32L176,100.69Z"}))],["fill",m.createElement(m.Fragment,null,m.createElement("path",{d:"M248,152a8,8,0,0,1-8,8H224v16a8,8,0,0,1-16,0V160H192a8,8,0,0,1,0-16h16V128a8,8,0,0,1,16,0v16h16A8,8,0,0,1,248,152ZM56,72H72V88a8,8,0,0,0,16,0V72h16a8,8,0,0,0,0-16H88V40a8,8,0,0,0-16,0V56H56a8,8,0,0,0,0,16ZM184,192h-8v-8a8,8,0,0,0-16,0v8h-8a8,8,0,0,0,0,16h8v8a8,8,0,0,0,16,0v-8h8a8,8,0,0,0,0-16ZM219.31,80,80,219.31a16,16,0,0,1-22.62,0L36.68,198.63a16,16,0,0,1,0-22.63L176,36.69a16,16,0,0,1,22.63,0l20.68,20.68A16,16,0,0,1,219.31,80ZM208,68.69,187.31,48l-32,32L176,100.69Z"}))],["light",m.createElement(m.Fragment,null,m.createElement("path",{d:"M246,152a6,6,0,0,1-6,6H222v18a6,6,0,0,1-12,0V158H192a6,6,0,0,1,0-12h18V128a6,6,0,0,1,12,0v18h18A6,6,0,0,1,246,152ZM56,70H74V88a6,6,0,0,0,12,0V70h18a6,6,0,0,0,0-12H86V40a6,6,0,0,0-12,0V58H56a6,6,0,0,0,0,12ZM184,194H174V184a6,6,0,0,0-12,0v10H152a6,6,0,0,0,0,12h10v10a6,6,0,0,0,12,0V206h10a6,6,0,0,0,0-12ZM217.9,78.59,78.58,217.9a14,14,0,0,1-19.8,0L38.09,197.21a14,14,0,0,1,0-19.8L177.41,38.1a14,14,0,0,1,19.8,0L217.9,58.79A14,14,0,0,1,217.9,78.59ZM167.51,112,144,88.49,46.58,185.9a2,2,0,0,0,0,2.83l20.69,20.68a2,2,0,0,0,2.82,0h0Zm41.9-44.73L188.73,46.59a2,2,0,0,0-2.83,0L152.48,80,176,103.52,209.41,70.1A2,2,0,0,0,209.41,67.27Z"}))],["regular",m.createElement(m.Fragment,null,m.createElement("path",{d:"M48,64a8,8,0,0,1,8-8H72V40a8,8,0,0,1,16,0V56h16a8,8,0,0,1,0,16H88V88a8,8,0,0,1-16,0V72H56A8,8,0,0,1,48,64ZM184,192h-8v-8a8,8,0,0,0-16,0v8h-8a8,8,0,0,0,0,16h8v8a8,8,0,0,0,16,0v-8h8a8,8,0,0,0,0-16Zm56-48H224V128a8,8,0,0,0-16,0v16H192a8,8,0,0,0,0,16h16v16a8,8,0,0,0,16,0V160h16a8,8,0,0,0,0-16ZM219.31,80,80,219.31a16,16,0,0,1-22.62,0L36.68,198.63a16,16,0,0,1,0-22.63L176,36.69a16,16,0,0,1,22.63,0l20.68,20.68A16,16,0,0,1,219.31,80Zm-54.63,32L144,91.31l-96,96L68.68,208ZM208,68.69,187.31,48l-32,32L176,100.69Z"}))],["thin",m.createElement(m.Fragment,null,m.createElement("path",{d:"M244,152a4,4,0,0,1-4,4H220v20a4,4,0,0,1-8,0V156H192a4,4,0,0,1,0-8h20V128a4,4,0,0,1,8,0v20h20A4,4,0,0,1,244,152ZM56,68H76V88a4,4,0,0,0,8,0V68h20a4,4,0,0,0,0-8H84V40a4,4,0,0,0-8,0V60H56a4,4,0,0,0,0,8ZM184,196H172V184a4,4,0,0,0-8,0v12H152a4,4,0,0,0,0,8h12v12a4,4,0,0,0,8,0V204h12a4,4,0,0,0,0-8ZM216.48,77.17,77.17,216.49a12,12,0,0,1-17,0L39.51,195.8a12,12,0,0,1,0-17L178.83,39.51a12,12,0,0,1,17,0L216.48,60.2A12,12,0,0,1,216.48,77.17ZM170.34,112,144,85.66,45.17,184.49a4,4,0,0,0,0,5.65l20.68,20.69a4,4,0,0,0,5.66,0Zm40.49-46.14L190.14,45.17a4,4,0,0,0-5.66,0L149.65,80,176,106.34l34.83-34.83A4,4,0,0,0,210.83,65.86Z"}))]]);var DA=Object.defineProperty,CA=Object.defineProperties,SA=Object.getOwnPropertyDescriptors,kf=Object.getOwnPropertySymbols,NA=Object.prototype.hasOwnProperty,TA=Object.prototype.propertyIsEnumerable,If=(t,e,n)=>e in t?DA(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n;const Mf=U.forwardRef(((t,e)=>m.createElement(Me,((t,e)=>CA(t,SA(e)))(((t,e)=>{for(var n in e||(e={}))NA.call(e,n)&&If(t,n,e[n]);if(kf)for(var n of kf(e))TA.call(e,n)&&If(t,n,e[n]);return t})({ref:e},t),{weights:yA}))));Mf.displayName="MagicWand";const RA=new Map([["bold",m.createElement(m.Fragment,null,m.createElement("path",{d:"M232.49,215.51,185,168a92.12,92.12,0,1,0-17,17l47.53,47.54a12,12,0,0,0,17-17ZM44,112a68,68,0,1,1,68,68A68.07,68.07,0,0,1,44,112Z"}))],["duotone",m.createElement(m.Fragment,null,m.createElement("path",{d:"M192,112a80,80,0,1,1-80-80A80,80,0,0,1,192,112Z",opacity:"0.2"}),m.createElement("path",{d:"M229.66,218.34,179.6,168.28a88.21,88.21,0,1,0-11.32,11.31l50.06,50.07a8,8,0,0,0,11.32-11.32ZM40,112a72,72,0,1,1,72,72A72.08,72.08,0,0,1,40,112Z"}))],["fill",m.createElement(m.Fragment,null,m.createElement("path",{d:"M168,112a56,56,0,1,1-56-56A56,56,0,0,1,168,112Zm61.66,117.66a8,8,0,0,1-11.32,0l-50.06-50.07a88,88,0,1,1,11.32-11.31l50.06,50.06A8,8,0,0,1,229.66,229.66ZM112,184a72,72,0,1,0-72-72A72.08,72.08,0,0,0,112,184Z"}))],["light",m.createElement(m.Fragment,null,m.createElement("path",{d:"M228.24,219.76l-51.38-51.38a86.15,86.15,0,1,0-8.48,8.48l51.38,51.38a6,6,0,0,0,8.48-8.48ZM38,112a74,74,0,1,1,74,74A74.09,74.09,0,0,1,38,112Z"}))],["regular",m.createElement(m.Fragment,null,m.createElement("path",{d:"M229.66,218.34l-50.07-50.06a88.11,88.11,0,1,0-11.31,11.31l50.06,50.07a8,8,0,0,0,11.32-11.32ZM40,112a72,72,0,1,1,72,72A72.08,72.08,0,0,1,40,112Z"}))],["thin",m.createElement(m.Fragment,null,m.createElement("path",{d:"M226.83,221.17l-52.7-52.7a84.1,84.1,0,1,0-5.66,5.66l52.7,52.7a4,4,0,0,0,5.66-5.66ZM36,112a76,76,0,1,1,76,76A76.08,76.08,0,0,1,36,112Z"}))]]);var LA=Object.defineProperty,OA=Object.defineProperties,kA=Object.getOwnPropertyDescriptors,Ff=Object.getOwnPropertySymbols,IA=Object.prototype.hasOwnProperty,MA=Object.prototype.propertyIsEnumerable,Bf=(t,e,n)=>e in t?LA(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n;const Pf=U.forwardRef(((t,e)=>m.createElement(Me,((t,e)=>OA(t,kA(e)))(((t,e)=>{for(var n in e||(e={}))IA.call(e,n)&&Bf(t,n,e[n]);if(Ff)for(var n of Ff(e))MA.call(e,n)&&Bf(t,n,e[n]);return t})({ref:e},t),{weights:RA}))));Pf.displayName="MagnifyingGlass";const PA=new Map([["bold",m.createElement(m.Fragment,null,m.createElement("path",{d:"M225.86,110.48,57.8,14.58A20,20,0,0,0,29.16,38.67l30.61,89.21L29.16,217.33A20,20,0,0,0,48,244a20.1,20.1,0,0,0,9.81-2.58l.09-.06,168-96.07a20,20,0,0,0,0-34.81ZM55.24,215.23,81,140h55a12,12,0,0,0,0-24H81.07L55.25,40.76l152.69,87.13Z"}))],["duotone",m.createElement(m.Fragment,null,m.createElement("path",{d:"M219.91,134.86,51.93,231a8,8,0,0,1-11.44-9.67l31-90.71a7.89,7.89,0,0,0,0-5.38l-31-90.47a8,8,0,0,1,11.44-9.67l168,95.85A8,8,0,0,1,219.91,134.86Z",opacity:"0.2"}),m.createElement("path",{d:"M223.87,114l-168-95.89A16,16,0,0,0,32.93,37.32l31,90.47a.42.42,0,0,0,0,.1.3.3,0,0,0,0,.1l-31,90.67A16,16,0,0,0,48,240a16.14,16.14,0,0,0,7.92-2.1l167.91-96.05a16,16,0,0,0,.05-27.89ZM48,224l0-.09L78.14,136H136a8,8,0,0,0,0-16H78.22L48.06,32.12,48,32l168,95.83Z"}))],["fill",m.createElement(m.Fragment,null,m.createElement("path",{d:"M232,127.89a16,16,0,0,1-8.18,14L55.91,237.9A16.14,16.14,0,0,1,48,240a16,16,0,0,1-15.05-21.34L60.3,138.71A4,4,0,0,1,64.09,136H136a8,8,0,0,0,8-8.53,8.19,8.19,0,0,0-8.26-7.47H64.16a4,4,0,0,1-3.79-2.7l-27.44-80A16,16,0,0,1,55.85,18.07l168,95.89A16,16,0,0,1,232,127.89Z"}))],["light",m.createElement(m.Fragment,null,m.createElement("path",{d:"M222.88,115.69l-168-95.88a14,14,0,0,0-20,16.85l31,90.48,0,.07a2.11,2.11,0,0,1,0,1.42l-31,90.64A14,14,0,0,0,48,238a14.11,14.11,0,0,0,6.92-1.83L222.84,140.1a14,14,0,0,0,0-24.41Zm-5.95,14L49,225.73a1.87,1.87,0,0,1-2.27-.22,1.92,1.92,0,0,1-.56-2.28L76.7,134H136a6,6,0,0,0,0-12H76.78L46.14,32.7A2,2,0,0,1,49,30.25l168,95.89a1.93,1.93,0,0,1,1,1.74A2,2,0,0,1,216.93,129.66Z"}))],["regular",m.createElement(m.Fragment,null,m.createElement("path",{d:"M223.87,114l-168-95.89A16,16,0,0,0,32.93,37.32l31,90.47a.42.42,0,0,0,0,.1.3.3,0,0,0,0,.1l-31,90.67A16,16,0,0,0,48,240a16.14,16.14,0,0,0,7.92-2.1l167.91-96.05a16,16,0,0,0,.05-27.89ZM48,224l0-.09L78.14,136H136a8,8,0,0,0,0-16H78.22L48.06,32.12,48,32l168,95.83Z"}))],["thin",m.createElement(m.Fragment,null,m.createElement("path",{d:"M221.89,117.43l-168-95.88A12,12,0,0,0,36.7,36l31.05,90.48v.05a4.09,4.09,0,0,1,0,2.74L36.72,220A12,12,0,0,0,48,236a12.13,12.13,0,0,0,5.93-1.57l167.94-96.08a12,12,0,0,0,0-20.92Zm-4,14L50,227.47a4,4,0,0,1-5.7-4.88l31-90.59H136a4,4,0,0,0,0-8H75.35a.65.65,0,0,1,0-.13L44.25,33.37A4,4,0,0,1,50,28.52l168,95.87a4,4,0,0,1,0,7Z"}))]]);var UA=Object.defineProperty,qA=Object.defineProperties,HA=Object.getOwnPropertyDescriptors,Uf=Object.getOwnPropertySymbols,VA=Object.prototype.hasOwnProperty,$A=Object.prototype.propertyIsEnumerable,qf=(t,e,n)=>e in t?UA(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n;const Hf=U.forwardRef(((t,e)=>m.createElement(Me,((t,e)=>qA(t,HA(e)))(((t,e)=>{for(var n in e||(e={}))VA.call(e,n)&&qf(t,n,e[n]);if(Uf)for(var n of Uf(e))$A.call(e,n)&&qf(t,n,e[n]);return t})({ref:e},t),{weights:PA}))));Hf.displayName="PaperPlaneRight";const ZA=new Map([["bold",m.createElement(m.Fragment,null,m.createElement("path",{d:"M228,128a12,12,0,0,1-12,12H140v76a12,12,0,0,1-24,0V140H40a12,12,0,0,1,0-24h76V40a12,12,0,0,1,24,0v76h76A12,12,0,0,1,228,128Z"}))],["duotone",m.createElement(m.Fragment,null,m.createElement("path",{d:"M216,48V208a8,8,0,0,1-8,8H48a8,8,0,0,1-8-8V48a8,8,0,0,1,8-8H208A8,8,0,0,1,216,48Z",opacity:"0.2"}),m.createElement("path",{d:"M224,128a8,8,0,0,1-8,8H136v80a8,8,0,0,1-16,0V136H40a8,8,0,0,1,0-16h80V40a8,8,0,0,1,16,0v80h80A8,8,0,0,1,224,128Z"}))],["fill",m.createElement(m.Fragment,null,m.createElement("path",{d:"M208,32H48A16,16,0,0,0,32,48V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V48A16,16,0,0,0,208,32ZM184,136H136v48a8,8,0,0,1-16,0V136H72a8,8,0,0,1,0-16h48V72a8,8,0,0,1,16,0v48h48a8,8,0,0,1,0,16Z"}))],["light",m.createElement(m.Fragment,null,m.createElement("path",{d:"M222,128a6,6,0,0,1-6,6H134v82a6,6,0,0,1-12,0V134H40a6,6,0,0,1,0-12h82V40a6,6,0,0,1,12,0v82h82A6,6,0,0,1,222,128Z"}))],["regular",m.createElement(m.Fragment,null,m.createElement("path",{d:"M224,128a8,8,0,0,1-8,8H136v80a8,8,0,0,1-16,0V136H40a8,8,0,0,1,0-16h80V40a8,8,0,0,1,16,0v80h80A8,8,0,0,1,224,128Z"}))],["thin",m.createElement(m.Fragment,null,m.createElement("path",{d:"M220,128a4,4,0,0,1-4,4H132v84a4,4,0,0,1-8,0V132H40a4,4,0,0,1,0-8h84V40a4,4,0,0,1,8,0v84h84A4,4,0,0,1,220,128Z"}))]]);var jA=Object.defineProperty,WA=Object.defineProperties,KA=Object.getOwnPropertyDescriptors,Vf=Object.getOwnPropertySymbols,YA=Object.prototype.hasOwnProperty,XA=Object.prototype.propertyIsEnumerable,$f=(t,e,n)=>e in t?jA(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n;const zf=U.forwardRef(((t,e)=>m.createElement(Me,((t,e)=>WA(t,KA(e)))(((t,e)=>{for(var n in e||(e={}))YA.call(e,n)&&$f(t,n,e[n]);if(Vf)for(var n of Vf(e))XA.call(e,n)&&$f(t,n,e[n]);return t})({ref:e},t),{weights:ZA}))));zf.displayName="Plus";const e_=new Map([["bold",m.createElement(m.Fragment,null,m.createElement("path",{d:"M240.26,186.1,152.81,34.23h0a28.74,28.74,0,0,0-49.62,0L15.74,186.1a27.45,27.45,0,0,0,0,27.71A28.31,28.31,0,0,0,40.55,228h174.9a28.31,28.31,0,0,0,24.79-14.19A27.45,27.45,0,0,0,240.26,186.1Zm-20.8,15.7a4.46,4.46,0,0,1-4,2.2H40.55a4.46,4.46,0,0,1-4-2.2,3.56,3.56,0,0,1,0-3.73L124,46.2a4.77,4.77,0,0,1,8,0l87.44,151.87A3.56,3.56,0,0,1,219.46,201.8ZM116,136V104a12,12,0,0,1,24,0v32a12,12,0,0,1-24,0Zm28,40a16,16,0,1,1-16-16A16,16,0,0,1,144,176Z"}))],["duotone",m.createElement(m.Fragment,null,m.createElement("path",{d:"M215.46,216H40.54C27.92,216,20,202.79,26.13,192.09L113.59,40.22c6.3-11,22.52-11,28.82,0l87.46,151.87C236,202.79,228.08,216,215.46,216Z",opacity:"0.2"}),m.createElement("path",{d:"M236.8,188.09,149.35,36.22h0a24.76,24.76,0,0,0-42.7,0L19.2,188.09a23.51,23.51,0,0,0,0,23.72A24.35,24.35,0,0,0,40.55,224h174.9a24.35,24.35,0,0,0,21.33-12.19A23.51,23.51,0,0,0,236.8,188.09ZM222.93,203.8a8.5,8.5,0,0,1-7.48,4.2H40.55a8.5,8.5,0,0,1-7.48-4.2,7.59,7.59,0,0,1,0-7.72L120.52,44.21a8.75,8.75,0,0,1,15,0l87.45,151.87A7.59,7.59,0,0,1,222.93,203.8ZM120,144V104a8,8,0,0,1,16,0v40a8,8,0,0,1-16,0Zm20,36a12,12,0,1,1-12-12A12,12,0,0,1,140,180Z"}))],["fill",m.createElement(m.Fragment,null,m.createElement("path",{d:"M236.8,188.09,149.35,36.22h0a24.76,24.76,0,0,0-42.7,0L19.2,188.09a23.51,23.51,0,0,0,0,23.72A24.35,24.35,0,0,0,40.55,224h174.9a24.35,24.35,0,0,0,21.33-12.19A23.51,23.51,0,0,0,236.8,188.09ZM120,104a8,8,0,0,1,16,0v40a8,8,0,0,1-16,0Zm8,88a12,12,0,1,1,12-12A12,12,0,0,1,128,192Z"}))],["light",m.createElement(m.Fragment,null,m.createElement("path",{d:"M235.07,189.09,147.61,37.22h0a22.75,22.75,0,0,0-39.22,0L20.93,189.09a21.53,21.53,0,0,0,0,21.72A22.35,22.35,0,0,0,40.55,222h174.9a22.35,22.35,0,0,0,19.6-11.19A21.53,21.53,0,0,0,235.07,189.09ZM224.66,204.8a10.46,10.46,0,0,1-9.21,5.2H40.55a10.46,10.46,0,0,1-9.21-5.2,9.51,9.51,0,0,1,0-9.72L118.79,43.21a10.75,10.75,0,0,1,18.42,0l87.46,151.87A9.51,9.51,0,0,1,224.66,204.8ZM122,144V104a6,6,0,0,1,12,0v40a6,6,0,0,1-12,0Zm16,36a10,10,0,1,1-10-10A10,10,0,0,1,138,180Z"}))],["regular",m.createElement(m.Fragment,null,m.createElement("path",{d:"M236.8,188.09,149.35,36.22h0a24.76,24.76,0,0,0-42.7,0L19.2,188.09a23.51,23.51,0,0,0,0,23.72A24.35,24.35,0,0,0,40.55,224h174.9a24.35,24.35,0,0,0,21.33-12.19A23.51,23.51,0,0,0,236.8,188.09ZM222.93,203.8a8.5,8.5,0,0,1-7.48,4.2H40.55a8.5,8.5,0,0,1-7.48-4.2,7.59,7.59,0,0,1,0-7.72L120.52,44.21a8.75,8.75,0,0,1,15,0l87.45,151.87A7.59,7.59,0,0,1,222.93,203.8ZM120,144V104a8,8,0,0,1,16,0v40a8,8,0,0,1-16,0Zm20,36a12,12,0,1,1-12-12A12,12,0,0,1,140,180Z"}))],["thin",m.createElement(m.Fragment,null,m.createElement("path",{d:"M233.34,190.09,145.88,38.22h0a20.75,20.75,0,0,0-35.76,0L22.66,190.09a19.52,19.52,0,0,0,0,19.71A20.36,20.36,0,0,0,40.54,220H215.46a20.36,20.36,0,0,0,17.86-10.2A19.52,19.52,0,0,0,233.34,190.09ZM226.4,205.8a12.47,12.47,0,0,1-10.94,6.2H40.54a12.47,12.47,0,0,1-10.94-6.2,11.45,11.45,0,0,1,0-11.72L117.05,42.21a12.76,12.76,0,0,1,21.9,0L226.4,194.08A11.45,11.45,0,0,1,226.4,205.8ZM124,144V104a4,4,0,0,1,8,0v40a4,4,0,0,1-8,0Zm12,36a8,8,0,1,1-8-8A8,8,0,0,1,136,180Z"}))]]);var t_=Object.defineProperty,n_=Object.defineProperties,r_=Object.getOwnPropertyDescriptors,Gf=Object.getOwnPropertySymbols,o_=Object.prototype.hasOwnProperty,a_=Object.prototype.propertyIsEnumerable,Zf=(t,e,n)=>e in t?t_(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n;const yu=U.forwardRef(((t,e)=>m.createElement(Me,((t,e)=>n_(t,r_(e)))(((t,e)=>{for(var n in e||(e={}))o_.call(e,n)&&Zf(t,n,e[n]);if(Gf)for(var n of Gf(e))a_.call(e,n)&&Zf(t,n,e[n]);return t})({ref:e},t),{weights:e_}))));yu.displayName="Warning";const l_=new Map([["bold",m.createElement(m.Fragment,null,m.createElement("path",{d:"M208.49,191.51a12,12,0,0,1-17,17L128,145,64.49,208.49a12,12,0,0,1-17-17L111,128,47.51,64.49a12,12,0,0,1,17-17L128,111l63.51-63.52a12,12,0,0,1,17,17L145,128Z"}))],["duotone",m.createElement(m.Fragment,null,m.createElement("path",{d:"M216,48V208a8,8,0,0,1-8,8H48a8,8,0,0,1-8-8V48a8,8,0,0,1,8-8H208A8,8,0,0,1,216,48Z",opacity:"0.2"}),m.createElement("path",{d:"M205.66,194.34a8,8,0,0,1-11.32,11.32L128,139.31,61.66,205.66a8,8,0,0,1-11.32-11.32L116.69,128,50.34,61.66A8,8,0,0,1,61.66,50.34L128,116.69l66.34-66.35a8,8,0,0,1,11.32,11.32L139.31,128Z"}))],["fill",m.createElement(m.Fragment,null,m.createElement("path",{d:"M208,32H48A16,16,0,0,0,32,48V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V48A16,16,0,0,0,208,32ZM181.66,170.34a8,8,0,0,1-11.32,11.32L128,139.31,85.66,181.66a8,8,0,0,1-11.32-11.32L116.69,128,74.34,85.66A8,8,0,0,1,85.66,74.34L128,116.69l42.34-42.35a8,8,0,0,1,11.32,11.32L139.31,128Z"}))],["light",m.createElement(m.Fragment,null,m.createElement("path",{d:"M204.24,195.76a6,6,0,1,1-8.48,8.48L128,136.49,60.24,204.24a6,6,0,0,1-8.48-8.48L119.51,128,51.76,60.24a6,6,0,0,1,8.48-8.48L128,119.51l67.76-67.75a6,6,0,0,1,8.48,8.48L136.49,128Z"}))],["regular",m.createElement(m.Fragment,null,m.createElement("path",{d:"M205.66,194.34a8,8,0,0,1-11.32,11.32L128,139.31,61.66,205.66a8,8,0,0,1-11.32-11.32L116.69,128,50.34,61.66A8,8,0,0,1,61.66,50.34L128,116.69l66.34-66.35a8,8,0,0,1,11.32,11.32L139.31,128Z"}))],["thin",m.createElement(m.Fragment,null,m.createElement("path",{d:"M202.83,197.17a4,4,0,0,1-5.66,5.66L128,133.66,58.83,202.83a4,4,0,0,1-5.66-5.66L122.34,128,53.17,58.83a4,4,0,0,1,5.66-5.66L128,122.34l69.17-69.17a4,4,0,1,1,5.66,5.66L133.66,128Z"}))]]);var u_=Object.defineProperty,c_=Object.defineProperties,d_=Object.getOwnPropertyDescriptors,jf=Object.getOwnPropertySymbols,p_=Object.prototype.hasOwnProperty,f_=Object.prototype.propertyIsEnumerable,Wf=(t,e,n)=>e in t?u_(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n;const Kf=U.forwardRef(((t,e)=>m.createElement(Me,((t,e)=>c_(t,d_(e)))(((t,e)=>{for(var n in e||(e={}))p_.call(e,n)&&Wf(t,n,e[n]);if(jf)for(var n of jf(e))f_.call(e,n)&&Wf(t,n,e[n]);return t})({ref:e},t),{weights:l_}))));Kf.displayName="X";const Du={plus:zf,chatBubble:gf,support:Of,search2:cf,search:Pf,magic:Mf};function h_({settings:t,isOpen:e,toggleOpen:n}){if(e)return null;const r=Du.hasOwnProperty(null==t?void 0:t.chatIcon)?Du[t.chatIcon]:Du.plus;return w.jsx("button",{style:{backgroundColor:t.buttonColor},id:"anything-llm-embed-chat-button",onClick:n,className:"hover:allm-cursor-pointer allm-border-none allm-flex allm-items-center allm-justify-center allm-p-4 allm-rounded-full allm-text-white allm-text-2xl hover:allm-opacity-95","aria-label":"Toggle Menu",children:w.jsx(r,{className:"text-white"})})}const qo="data:image/svg+xml,%3csvg%20width='49'%20height='49'%20viewBox='0%200%2049%2049'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3crect%20x='0.898438'%20y='0.5'%20width='48'%20height='48'%20rx='24'%20fill='%23222628'%20fill-opacity='0.8'/%3e%3cpath%20fill-rule='evenodd'%20clip-rule='evenodd'%20d='M12.0173%2014.2937C10.4387%2014.2937%209.14844%2015.584%209.14844%2017.1626V31.8372C9.14844%2033.4156%2010.4365%2034.7061%2012.0173%2034.7061H17.5428C18.4316%2034.7061%2019.2557%2034.3035%2019.8034%2033.6063L19.8041%2033.6054L32.4126%2017.4869H37.4552V31.509H32.4204L29.8951%2027.9721L29.8867%2027.9615C29.4483%2027.4042%2028.602%2027.4042%2028.1635%2027.9615L27.52%2028.7815L27.5178%2028.7843C27.2188%2029.1751%2027.2113%2029.7217%2027.512%2030.1178L29.985%2033.5936L29.9935%2033.6044C30.5415%2034.302%2031.3696%2034.7042%2032.2541%2034.7042H37.7795C39.3643%2034.7042%2040.6484%2033.4175%2040.6484%2031.8353V17.1626C40.6484%2015.5827%2039.3646%2014.2937%2037.7795%2014.2937H32.2541C31.3673%2014.2937%2030.5407%2014.6964%2029.9928%2015.3964L17.3858%2031.511H12.3417V17.4889H17.3757L20.133%2021.2573L20.1386%2021.2645C20.5782%2021.8273%2021.4253%2021.8239%2021.8647%2021.2666L21.8661%2021.2648L22.505%2020.4477L22.5069%2020.4453C22.8064%2020.0538%2022.8139%2019.5046%2022.5076%2019.1075L19.8102%2015.4041L19.804%2015.3963C19.2562%2014.6965%2018.4318%2014.2937%2017.5428%2014.2937H12.0173Z'%20fill='white'/%3e%3cpath%20d='M19.8034%2033.6063L20.0392%2033.7915L20.0394%2033.7912L19.8034%2033.6063ZM19.8041%2033.6054L20.0401%2033.7903L20.0403%2033.7901L19.8041%2033.6054ZM32.4126%2017.4869V17.1871H32.2665L32.1764%2017.3022L32.4126%2017.4869ZM37.4552%2017.4869H37.755V17.1871H37.4552V17.4869ZM37.4552%2031.509V31.8089H37.755V31.509H37.4552ZM32.4204%2031.509L32.1763%2031.6833L32.266%2031.8089H32.4204V31.509ZM29.8951%2027.9721L30.1394%2027.7977L30.1307%2027.7867L29.8951%2027.9721ZM29.8867%2027.9615L29.6511%2028.1469L29.6511%2028.1469L29.8867%2027.9615ZM28.1635%2027.9615L27.9279%2027.7761L27.9277%2027.7764L28.1635%2027.9615ZM27.52%2028.7815L27.2841%2028.5964L27.2819%2028.5993L27.52%2028.7815ZM27.5178%2028.7843L27.7559%2028.9665L27.7559%2028.9665L27.5178%2028.7843ZM27.512%2030.1178L27.7564%2029.9439L27.7508%2029.9365L27.512%2030.1178ZM29.985%2033.5936L29.7407%2033.7674L29.7448%2033.7732L29.7492%2033.7788L29.985%2033.5936ZM29.9935%2033.6044L30.2293%2033.4191L30.2293%2033.4191L29.9935%2033.6044ZM29.9928%2015.3964L29.7567%2015.2116L29.7566%2015.2116L29.9928%2015.3964ZM17.3858%2031.511V31.8108H17.5319L17.6219%2031.6957L17.3858%2031.511ZM12.3417%2031.511H12.0418V31.8108H12.3417V31.511ZM12.3417%2017.4889V17.189H12.0418V17.4889H12.3417ZM17.3757%2017.4889L17.6177%2017.3118L17.5278%2017.189H17.3757V17.4889ZM20.133%2021.2573L19.8909%2021.4345L19.8967%2021.4419L20.133%2021.2573ZM20.1386%2021.2645L19.9023%2021.4491V21.4491L20.1386%2021.2645ZM21.8647%2021.2666L22.1001%2021.4522L22.1005%2021.4517L21.8647%2021.2666ZM21.8661%2021.2648L22.1019%2021.45L22.1023%2021.4495L21.8661%2021.2648ZM22.505%2020.4477L22.7412%2020.6324L22.7431%2020.63L22.505%2020.4477ZM22.5069%2020.4453L22.7449%2020.6276L22.745%2020.6275L22.5069%2020.4453ZM22.5076%2019.1075L22.2651%2019.2841L22.2702%2019.2907L22.5076%2019.1075ZM19.8102%2015.4041L20.0527%2015.2275L20.0463%2015.2193L19.8102%2015.4041ZM19.804%2015.3963L19.5679%2015.5811L19.5679%2015.5811L19.804%2015.3963ZM9.44828%2017.1626C9.44828%2015.7496%2010.6043%2014.5935%2012.0173%2014.5935V13.9939C10.2731%2013.9939%208.8486%2015.4184%208.8486%2017.1626H9.44828ZM9.44828%2031.8372V17.1626H8.8486V31.8372H9.44828ZM12.0173%2034.4063C10.6022%2034.4063%209.44828%2033.2501%209.44828%2031.8372H8.8486C8.8486%2033.581%2010.2707%2035.006%2012.0173%2035.006V34.4063ZM17.5428%2034.4063H12.0173V35.006H17.5428V34.4063ZM19.5676%2033.4211C19.0766%2034.0462%2018.3393%2034.4063%2017.5428%2034.4063V35.006C18.524%2035.006%2019.4349%2034.5608%2020.0392%2033.7915L19.5676%2033.4211ZM19.5681%2033.4205L19.5674%2033.4214L20.0394%2033.7912L20.0401%2033.7903L19.5681%2033.4205ZM32.1764%2017.3022L19.5679%2033.4206L20.0403%2033.7901L32.6488%2017.6717L32.1764%2017.3022ZM37.4552%2017.1871H32.4126V17.7868H37.4552V17.1871ZM37.755%2031.509V17.4869H37.1553V31.509H37.755ZM32.4204%2031.8089H37.4552V31.2092H32.4204V31.8089ZM29.651%2028.1464L32.1763%2031.6833L32.6644%2031.3348L30.1391%2027.7979L29.651%2028.1464ZM29.6511%2028.1469L29.6594%2028.1575L30.1307%2027.7867L30.1224%2027.7761L29.6511%2028.1469ZM28.3992%2028.1469C28.7176%2027.7422%2029.3327%2027.7422%2029.6511%2028.1469L30.1224%2027.7761C29.5639%2027.0662%2028.4864%2027.0662%2027.9279%2027.7761L28.3992%2028.1469ZM27.7558%2028.9666L28.3994%2028.1466L27.9277%2027.7764L27.2841%2028.5964L27.7558%2028.9666ZM27.7559%2028.9665L27.7581%2028.9637L27.2819%2028.5993L27.2797%2028.6021L27.7559%2028.9665ZM27.7508%2029.9365C27.5333%2029.65%2027.5374%2029.2521%2027.7559%2028.9665L27.2797%2028.6021C26.9002%2029.098%2026.8893%2029.7935%2027.2732%2030.2991L27.7508%2029.9365ZM30.2293%2033.4197L27.7563%2029.944L27.2677%2030.2916L29.7407%2033.7674L30.2293%2033.4197ZM30.2293%2033.4191L30.2208%2033.4083L29.7492%2033.7788L29.7577%2033.7896L30.2293%2033.4191ZM32.2541%2034.4044C31.4617%2034.4044%2030.7205%2034.0445%2030.2293%2033.4191L29.7577%2033.7896C30.3625%2034.5595%2031.2775%2035.0041%2032.2541%2035.0041V34.4044ZM37.7795%2034.4044H32.2541V35.0041H37.7795V34.4044ZM40.3486%2031.8353C40.3486%2033.2521%2039.1985%2034.4044%2037.7795%2034.4044V35.0041C39.5301%2035.0041%2040.9483%2033.5829%2040.9483%2031.8353H40.3486ZM40.3486%2017.1626V31.8353H40.9483V17.1626H40.3486ZM37.7795%2014.5935C39.1987%2014.5935%2040.3486%2015.7479%2040.3486%2017.1626H40.9483C40.9483%2015.4174%2039.5305%2013.9939%2037.7795%2013.9939V14.5935ZM32.2541%2014.5935H37.7795V13.9939H32.2541V14.5935ZM30.2289%2015.5812C30.72%2014.9537%2031.4596%2014.5935%2032.2541%2014.5935V13.9939C31.2749%2013.9939%2030.3613%2014.4391%2029.7567%2015.2116L30.2289%2015.5812ZM17.6219%2031.6957L30.2289%2015.5811L29.7566%2015.2116L17.1496%2031.3262L17.6219%2031.6957ZM12.3417%2031.8108H17.3858V31.2111H12.3417V31.8108ZM12.0418%2017.4889V31.511H12.6415V17.4889H12.0418ZM17.3757%2017.189H12.3417V17.7887H17.3757V17.189ZM20.375%2021.0803L17.6177%2017.3118L17.1337%2017.6659L19.891%2021.4344L20.375%2021.0803ZM20.3749%2021.08L20.3693%2021.0728L19.8967%2021.4419L19.9023%2021.4491L20.3749%2021.08ZM21.6292%2021.0809C21.3091%2021.4869%2020.6937%2021.488%2020.3749%2021.08L19.9023%2021.4491C20.4627%2022.1665%2021.5415%2022.1608%2022.1001%2021.4522L21.6292%2021.0809ZM21.6302%2021.0796L21.6288%2021.0814L22.1005%2021.4517L22.1019%2021.45L21.6302%2021.0796ZM22.2688%2020.263L21.6299%2021.0801L22.1023%2021.4495L22.7412%2020.6324L22.2688%2020.263ZM22.2688%2020.263L22.2669%2020.2654L22.7431%2020.63L22.7449%2020.6276L22.2688%2020.263ZM22.2702%2019.2907C22.4916%2019.5777%2022.4877%2019.977%2022.2687%2020.2631L22.745%2020.6275C23.1252%2020.1307%2023.1363%2019.4315%2022.7449%2018.9243L22.2702%2019.2907ZM19.5678%2015.5807L22.2652%2019.284L22.7499%2018.931L20.0525%2015.2276L19.5678%2015.5807ZM19.5679%2015.5811L19.5741%2015.589L20.0463%2015.2193L20.0401%2015.2114L19.5679%2015.5811ZM17.5428%2014.5935C18.3394%2014.5935%2019.0768%2014.9537%2019.5679%2015.5811L20.0401%2015.2114C19.4357%2014.4393%2018.5243%2013.9939%2017.5428%2013.9939V14.5935ZM12.0173%2014.5935H17.5428V13.9939H12.0173V14.5935Z'%20fill='white'/%3e%3c/svg%3e";function b_(t){let e,n,r,o=!1;return function(s){void 0===e?(e=s,n=0,r=-1):e=function(t,e){const n=new Uint8Array(t.length+e.length);return n.set(t),n.set(e,t.length),n}(e,s);const i=e.length;let l=0;for(;n{const f=Object.assign({},r);let b;function A(){b.abort(),document.hidden||N()}f.accept||(f.accept=Cu),l||document.addEventListener("visibilitychange",A);let y=1e3,h=0;function g(){document.removeEventListener("visibilitychange",A),window.clearTimeout(h),b.abort()}null==n||n.addEventListener("abort",(()=>{g(),p()}));const E=u??window.fetch,_=o??C_;async function N(){var v;b=new AbortController;try{const T=await E(t,Object.assign(Object.assign({},c),{headers:f,signal:b.signal}));await _(T),await async function(t,e){const n=t.getReader();let r;for(;!(r=await n.read()).done;)e(r.value)}(T.body,b_(function(t,e,n){let r={data:"",event:"",id:"",retry:void 0};const o=new TextDecoder;return function(s,i){if(0===s.length)null==n||n(r),r={data:"",event:"",id:"",retry:void 0};else if(i>0){const l=o.decode(s.subarray(0,i)),u=i+(32===s[i+1]?2:1),c=o.decode(s.subarray(u));switch(l){case"data":r.data=r.data?r.data+"\n"+c:c;break;case"event":r.event=c;break;case"id":t(r.id=c);break;case"retry":const p=parseInt(c,10);isNaN(p)||e(r.retry=p)}}}}((R=>{R?f[Xf]=R:delete f[Xf]}),(R=>{y=R}),a))),null==s||s(),g(),p()}catch(T){if(!b.signal.aborted)try{const R=null!==(v=null==i?void 0:i(T))&&void 0!==v?v:y;window.clearTimeout(h),h=window.setTimeout(N,R)}catch(R){g(),d(R)}}}N()}))}function C_(t){const e=t.headers.get("content-type");if(null==e||!e.startsWith(Cu))throw new Error(`Expected content-type to be ${Cu}, Actual: ${e}`)}const Cs={embedSessionHistory:async function(t,e){const{embedId:n,baseApiUrl:r}=t;return await fetch(`${r}/${n}/${e}`).then((o=>{if(o.ok)return o.json();throw new Error("Invalid response from server")})).then((o=>o.history.map((a=>({...a,id:Kn(),sender:"user"===a.role?"user":"system",textResponse:a.content,close:!1}))))).catch((o=>(console.error(o),[])))},resetEmbedChatSession:async function(t,e){const{baseApiUrl:n,embedId:r}=t;return await fetch(`${n}/${r}/${e}`,{method:"DELETE"}).then((o=>o.ok)).catch((()=>!1))},streamChat:async function(t,e,n,r){const{baseApiUrl:o,embedId:a,username:s}=e,i={prompt:(null==e?void 0:e.prompt)??null,model:(null==e?void 0:e.model)??null,temperature:(null==e?void 0:e.temperature)??null},l=new AbortController;await D_(`${o}/${a}/stream-chat`,{method:"POST",body:JSON.stringify({message:n,sessionId:t,username:s,...i}),signal:l.signal,openWhenHidden:!0,async onopen(u){if(!u.ok)throw u.status>=400?(await u.json().then((c=>{r(c)})).catch((()=>{r({id:Kn(),type:"abort",textResponse:null,sources:[],close:!0,error:`An error occurred while streaming response. Code ${u.status}`})})),l.abort(),new Error):(r({id:Kn(),type:"abort",textResponse:null,sources:[],close:!0,error:"An error occurred while streaming response. Unknown Error."}),l.abort(),new Error("Unknown Error"))},async onmessage(u){try{const c=JSON.parse(u.data);r(c)}catch{}},onerror(u){throw r({id:Kn(),type:"abort",textResponse:null,sources:[],close:!0,error:`An error occurred while streaming response. ${u.message}`}),l.abort(),new Error}})}};function Qf({sessionId:t,settings:e={},iconUrl:n=null,closeChat:r,setChatHistory:o}){const[a,s]=U.useState(!1),i=U.useRef(),l=U.useRef();return U.useEffect((()=>{function c(p){i.current&&!i.current.contains(p.target)&&l.current&&!l.current.contains(p.target)&&s(!1)}return document.addEventListener("mousedown",c),()=>{document.removeEventListener("mousedown",c)}}),[i]),w.jsxs("div",{style:{borderBottom:"1px solid #E9E9E9"},className:"allm-flex allm-items-center allm-relative allm-rounded-t-2xl",id:"anything-llm-header",children:[w.jsx("div",{className:"allm-flex allm-justify-center allm-items-center allm-w-full allm-h-[76px]",children:w.jsx("img",{style:{maxWidth:48,maxHeight:48},src:n??qo,alt:n?"Brand":"AnythingLLM Logo"})}),w.jsxs("div",{className:"allm-absolute allm-right-0 allm-flex allm-gap-x-1 allm-items-center allm-px-[22px]",children:[e.loaded&&w.jsx("button",{ref:l,type:"button",onClick:()=>s(!a),className:"allm-bg-transparent hover:allm-cursor-pointer allm-border-none hover:allm-bg-gray-100 allm-rounded-sm allm-text-slate-800/60","aria-label":"Options",children:w.jsx(Nf,{size:20,weight:"fill"})}),w.jsx("button",{type:"button",onClick:r,className:"allm-bg-transparent hover:allm-cursor-pointer allm-border-none hover:allm-bg-gray-100 allm-rounded-sm allm-text-slate-800/60","aria-label":"Close",children:w.jsx(Kf,{size:20,weight:"bold"})})]}),w.jsx(S_,{settings:e,showing:a,resetChat:async()=>{await Cs.resetEmbedChatSession(e,t),o([]),s(!1)},sessionId:t,menuRef:i})]})}function S_({settings:t,showing:e,resetChat:n,sessionId:r,menuRef:o}){return e?w.jsxs("div",{ref:o,className:"allm-bg-white allm-absolute allm-z-10 allm-flex allm-flex-col allm-gap-y-1 allm-rounded-xl allm-shadow-lg allm-top-[64px] allm-right-[46px]",children:[w.jsxs("button",{onClick:n,className:"hover:allm-cursor-pointer allm-bg-white allm-gap-x-[12px] hover:allm-bg-gray-100 allm-rounded-lg allm-border-none allm-flex allm-items-center allm-text-base allm-text-[#7A7D7E] allm-font-bold allm-px-4",children:[w.jsx(rf,{size:24}),w.jsx("p",{className:"allm-text-[14px]",children:"Reset Chat"})]}),w.jsx(T_,{email:t.supportEmail}),w.jsx(N_,{sessionId:r})]}):null}function N_({sessionId:t}){if(!t)return null;const[e,n]=U.useState(!1);return e?w.jsxs("div",{className:"hover:allm-cursor-pointer allm-bg-white allm-gap-x-[12px] hover:allm-bg-gray-100 allm-rounded-lg allm-border-none allm-flex allm-items-center allm-text-base allm-text-[#7A7D7E] allm-font-bold allm-px-4",children:[w.jsx(bf,{size:24}),w.jsx("p",{className:"allm-text-[14px] allm-font-sans",children:"Copied!"})]}):w.jsxs("button",{onClick:()=>{navigator.clipboard.writeText(t),n(!0),setTimeout((()=>n(!1)),1e3)},className:"hover:allm-cursor-pointer allm-bg-white allm-gap-x-[12px] hover:allm-bg-gray-100 allm-rounded-lg allm-border-none allm-flex allm-items-center allm-text-base allm-text-[#7A7D7E] allm-font-bold allm-px-4",children:[w.jsx(Df,{size:24}),w.jsx("p",{className:"allm-text-[14px]",children:"Session ID"})]})}function T_({email:t=null}){if(!t)return null;const e=`Inquiry from ${window.location.origin}`;return w.jsxs("a",{href:`mailto:${t}?Subject=${encodeURIComponent(e)}`,className:"allm-no-underline hover:allm-underline hover:allm-cursor-pointer allm-bg-white allm-gap-x-[12px] hover:allm-bg-gray-100 allm-rounded-lg allm-border-none allm-flex allm-items-center allm-text-base allm-text-[#7A7D7E] allm-font-bold allm-px-4",children:[w.jsx(xf,{size:24}),w.jsx("p",{className:"allm-text-[14px] allm-font-sans",children:"Email Support"})]})}function w_(){const t=K0();return t?w.jsx("div",{className:"allm-text-xs allm-text-gray-300 allm-w-full allm-text-center",children:t}):null}var Ss={exports:{}};/*! https://mths.be/he v1.2.0 by @mathias | MIT license */!function(t,e){!function(n){var r=e,o=t&&t.exports==r&&t,a="object"==typeof xe&&xe;(a.global===a||a.window===a)&&(n=a);var s=/[\uD800-\uDBFF][\uDC00-\uDFFF]/g,i=/[\x01-\x7F]/g,l=/[\x01-\t\x0B\f\x0E-\x1F\x7F\x81\x8D\x8F\x90\x9D\xA0-\uFFFF]/g,u=/<\u20D2|=\u20E5|>\u20D2|\u205F\u200A|\u219D\u0338|\u2202\u0338|\u2220\u20D2|\u2229\uFE00|\u222A\uFE00|\u223C\u20D2|\u223D\u0331|\u223E\u0333|\u2242\u0338|\u224B\u0338|\u224D\u20D2|\u224E\u0338|\u224F\u0338|\u2250\u0338|\u2261\u20E5|\u2264\u20D2|\u2265\u20D2|\u2266\u0338|\u2267\u0338|\u2268\uFE00|\u2269\uFE00|\u226A\u0338|\u226A\u20D2|\u226B\u0338|\u226B\u20D2|\u227F\u0338|\u2282\u20D2|\u2283\u20D2|\u228A\uFE00|\u228B\uFE00|\u228F\u0338|\u2290\u0338|\u2293\uFE00|\u2294\uFE00|\u22B4\u20D2|\u22B5\u20D2|\u22D8\u0338|\u22D9\u0338|\u22DA\uFE00|\u22DB\uFE00|\u22F5\u0338|\u22F9\u0338|\u2933\u0338|\u29CF\u0338|\u29D0\u0338|\u2A6D\u0338|\u2A70\u0338|\u2A7D\u0338|\u2A7E\u0338|\u2AA1\u0338|\u2AA2\u0338|\u2AAC\uFE00|\u2AAD\uFE00|\u2AAF\u0338|\u2AB0\u0338|\u2AC5\u0338|\u2AC6\u0338|\u2ACB\uFE00|\u2ACC\uFE00|\u2AFD\u20E5|[\xA0-\u0113\u0116-\u0122\u0124-\u012B\u012E-\u014D\u0150-\u017E\u0192\u01B5\u01F5\u0237\u02C6\u02C7\u02D8-\u02DD\u0311\u0391-\u03A1\u03A3-\u03A9\u03B1-\u03C9\u03D1\u03D2\u03D5\u03D6\u03DC\u03DD\u03F0\u03F1\u03F5\u03F6\u0401-\u040C\u040E-\u044F\u0451-\u045C\u045E\u045F\u2002-\u2005\u2007-\u2010\u2013-\u2016\u2018-\u201A\u201C-\u201E\u2020-\u2022\u2025\u2026\u2030-\u2035\u2039\u203A\u203E\u2041\u2043\u2044\u204F\u2057\u205F-\u2063\u20AC\u20DB\u20DC\u2102\u2105\u210A-\u2113\u2115-\u211E\u2122\u2124\u2127-\u2129\u212C\u212D\u212F-\u2131\u2133-\u2138\u2145-\u2148\u2153-\u215E\u2190-\u219B\u219D-\u21A7\u21A9-\u21AE\u21B0-\u21B3\u21B5-\u21B7\u21BA-\u21DB\u21DD\u21E4\u21E5\u21F5\u21FD-\u2205\u2207-\u2209\u220B\u220C\u220F-\u2214\u2216-\u2218\u221A\u221D-\u2238\u223A-\u2257\u2259\u225A\u225C\u225F-\u2262\u2264-\u228B\u228D-\u229B\u229D-\u22A5\u22A7-\u22B0\u22B2-\u22BB\u22BD-\u22DB\u22DE-\u22E3\u22E6-\u22F7\u22F9-\u22FE\u2305\u2306\u2308-\u2310\u2312\u2313\u2315\u2316\u231C-\u231F\u2322\u2323\u232D\u232E\u2336\u233D\u233F\u237C\u23B0\u23B1\u23B4-\u23B6\u23DC-\u23DF\u23E2\u23E7\u2423\u24C8\u2500\u2502\u250C\u2510\u2514\u2518\u251C\u2524\u252C\u2534\u253C\u2550-\u256C\u2580\u2584\u2588\u2591-\u2593\u25A1\u25AA\u25AB\u25AD\u25AE\u25B1\u25B3-\u25B5\u25B8\u25B9\u25BD-\u25BF\u25C2\u25C3\u25CA\u25CB\u25EC\u25EF\u25F8-\u25FC\u2605\u2606\u260E\u2640\u2642\u2660\u2663\u2665\u2666\u266A\u266D-\u266F\u2713\u2717\u2720\u2736\u2758\u2772\u2773\u27C8\u27C9\u27E6-\u27ED\u27F5-\u27FA\u27FC\u27FF\u2902-\u2905\u290C-\u2913\u2916\u2919-\u2920\u2923-\u292A\u2933\u2935-\u2939\u293C\u293D\u2945\u2948-\u294B\u294E-\u2976\u2978\u2979\u297B-\u297F\u2985\u2986\u298B-\u2996\u299A\u299C\u299D\u29A4-\u29B7\u29B9\u29BB\u29BC\u29BE-\u29C5\u29C9\u29CD-\u29D0\u29DC-\u29DE\u29E3-\u29E5\u29EB\u29F4\u29F6\u2A00-\u2A02\u2A04\u2A06\u2A0C\u2A0D\u2A10-\u2A17\u2A22-\u2A27\u2A29\u2A2A\u2A2D-\u2A31\u2A33-\u2A3C\u2A3F\u2A40\u2A42-\u2A4D\u2A50\u2A53-\u2A58\u2A5A-\u2A5D\u2A5F\u2A66\u2A6A\u2A6D-\u2A75\u2A77-\u2A9A\u2A9D-\u2AA2\u2AA4-\u2AB0\u2AB3-\u2AC8\u2ACB\u2ACC\u2ACF-\u2ADB\u2AE4\u2AE6-\u2AE9\u2AEB-\u2AF3\u2AFD\uFB00-\uFB04]|\uD835[\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDCCF\uDD04\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDD6B]/g,c={"­":"shy","‌":"zwnj","‍":"zwj","‎":"lrm","⁣":"ic","⁢":"it","⁡":"af","‏":"rlm","​":"ZeroWidthSpace","⁠":"NoBreak","̑":"DownBreve","⃛":"tdot","⃜":"DotDot","\t":"Tab","\n":"NewLine"," ":"puncsp"," ":"MediumSpace"," ":"thinsp"," ":"hairsp"," ":"emsp13"," ":"ensp"," ":"emsp14"," ":"emsp"," ":"numsp"," ":"nbsp","  ":"ThickSpace","‾":"oline",_:"lowbar","‐":"dash","–":"ndash","—":"mdash","―":"horbar",",":"comma",";":"semi","⁏":"bsemi",":":"colon","⩴":"Colone","!":"excl","¡":"iexcl","?":"quest","¿":"iquest",".":"period","‥":"nldr","…":"mldr","·":"middot","'":"apos","‘":"lsquo","’":"rsquo","‚":"sbquo","‹":"lsaquo","›":"rsaquo",'"':"quot","“":"ldquo","”":"rdquo","„":"bdquo","«":"laquo","»":"raquo","(":"lpar",")":"rpar","[":"lsqb","]":"rsqb","{":"lcub","}":"rcub","⌈":"lceil","⌉":"rceil","⌊":"lfloor","⌋":"rfloor","⦅":"lopar","⦆":"ropar","⦋":"lbrke","⦌":"rbrke","⦍":"lbrkslu","⦎":"rbrksld","⦏":"lbrksld","⦐":"rbrkslu","⦑":"langd","⦒":"rangd","⦓":"lparlt","⦔":"rpargt","⦕":"gtlPar","⦖":"ltrPar","⟦":"lobrk","⟧":"robrk","⟨":"lang","⟩":"rang","⟪":"Lang","⟫":"Rang","⟬":"loang","⟭":"roang","❲":"lbbrk","❳":"rbbrk","‖":"Vert","§":"sect","¶":"para","@":"commat","*":"ast","/":"sol",undefined:null,"&":"amp","#":"num","%":"percnt","‰":"permil","‱":"pertenk","†":"dagger","‡":"Dagger","•":"bull","⁃":"hybull","′":"prime","″":"Prime","‴":"tprime","⁗":"qprime","‵":"bprime","⁁":"caret","`":"grave","´":"acute","˜":"tilde","^":"Hat","¯":"macr","˘":"breve","˙":"dot","¨":"die","˚":"ring","˝":"dblac","¸":"cedil","˛":"ogon","ˆ":"circ","ˇ":"caron","°":"deg","©":"copy","®":"reg","℗":"copysr","℘":"wp","℞":"rx","℧":"mho","℩":"iiota","←":"larr","↚":"nlarr","→":"rarr","↛":"nrarr","↑":"uarr","↓":"darr","↔":"harr","↮":"nharr","↕":"varr","↖":"nwarr","↗":"nearr","↘":"searr","↙":"swarr","↝":"rarrw","↝̸":"nrarrw","↞":"Larr","↟":"Uarr","↠":"Rarr","↡":"Darr","↢":"larrtl","↣":"rarrtl","↤":"mapstoleft","↥":"mapstoup","↦":"map","↧":"mapstodown","↩":"larrhk","↪":"rarrhk","↫":"larrlp","↬":"rarrlp","↭":"harrw","↰":"lsh","↱":"rsh","↲":"ldsh","↳":"rdsh","↵":"crarr","↶":"cularr","↷":"curarr","↺":"olarr","↻":"orarr","↼":"lharu","↽":"lhard","↾":"uharr","↿":"uharl","⇀":"rharu","⇁":"rhard","⇂":"dharr","⇃":"dharl","⇄":"rlarr","⇅":"udarr","⇆":"lrarr","⇇":"llarr","⇈":"uuarr","⇉":"rrarr","⇊":"ddarr","⇋":"lrhar","⇌":"rlhar","⇐":"lArr","⇍":"nlArr","⇑":"uArr","⇒":"rArr","⇏":"nrArr","⇓":"dArr","⇔":"iff","⇎":"nhArr","⇕":"vArr","⇖":"nwArr","⇗":"neArr","⇘":"seArr","⇙":"swArr","⇚":"lAarr","⇛":"rAarr","⇝":"zigrarr","⇤":"larrb","⇥":"rarrb","⇵":"duarr","⇽":"loarr","⇾":"roarr","⇿":"hoarr","∀":"forall","∁":"comp","∂":"part","∂̸":"npart","∃":"exist","∄":"nexist","∅":"empty","∇":"Del","∈":"in","∉":"notin","∋":"ni","∌":"notni","϶":"bepsi","∏":"prod","∐":"coprod","∑":"sum","+":"plus","±":"pm","÷":"div","×":"times","<":"lt","≮":"nlt","<⃒":"nvlt","=":"equals","≠":"ne","=⃥":"bne","⩵":"Equal",">":"gt","≯":"ngt",">⃒":"nvgt","¬":"not","|":"vert","¦":"brvbar","−":"minus","∓":"mp","∔":"plusdo","⁄":"frasl","∖":"setmn","∗":"lowast","∘":"compfn","√":"Sqrt","∝":"prop","∞":"infin","∟":"angrt","∠":"ang","∠⃒":"nang","∡":"angmsd","∢":"angsph","∣":"mid","∤":"nmid","∥":"par","∦":"npar","∧":"and","∨":"or","∩":"cap","∩︀":"caps","∪":"cup","∪︀":"cups","∫":"int","∬":"Int","∭":"tint","⨌":"qint","∮":"oint","∯":"Conint","∰":"Cconint","∱":"cwint","∲":"cwconint","∳":"awconint","∴":"there4","∵":"becaus","∶":"ratio","∷":"Colon","∸":"minusd","∺":"mDDot","∻":"homtht","∼":"sim","≁":"nsim","∼⃒":"nvsim","∽":"bsim","∽̱":"race","∾":"ac","∾̳":"acE","∿":"acd","≀":"wr","≂":"esim","≂̸":"nesim","≃":"sime","≄":"nsime","≅":"cong","≇":"ncong","≆":"simne","≈":"ap","≉":"nap","≊":"ape","≋":"apid","≋̸":"napid","≌":"bcong","≍":"CupCap","≭":"NotCupCap","≍⃒":"nvap","≎":"bump","≎̸":"nbump","≏":"bumpe","≏̸":"nbumpe","≐":"doteq","≐̸":"nedot","≑":"eDot","≒":"efDot","≓":"erDot","≔":"colone","≕":"ecolon","≖":"ecir","≗":"cire","≙":"wedgeq","≚":"veeeq","≜":"trie","≟":"equest","≡":"equiv","≢":"nequiv","≡⃥":"bnequiv","≤":"le","≰":"nle","≤⃒":"nvle","≥":"ge","≱":"nge","≥⃒":"nvge","≦":"lE","≦̸":"nlE","≧":"gE","≧̸":"ngE","≨︀":"lvnE","≨":"lnE","≩":"gnE","≩︀":"gvnE","≪":"ll","≪̸":"nLtv","≪⃒":"nLt","≫":"gg","≫̸":"nGtv","≫⃒":"nGt","≬":"twixt","≲":"lsim","≴":"nlsim","≳":"gsim","≵":"ngsim","≶":"lg","≸":"ntlg","≷":"gl","≹":"ntgl","≺":"pr","⊀":"npr","≻":"sc","⊁":"nsc","≼":"prcue","⋠":"nprcue","≽":"sccue","⋡":"nsccue","≾":"prsim","≿":"scsim","≿̸":"NotSucceedsTilde","⊂":"sub","⊄":"nsub","⊂⃒":"vnsub","⊃":"sup","⊅":"nsup","⊃⃒":"vnsup","⊆":"sube","⊈":"nsube","⊇":"supe","⊉":"nsupe","⊊︀":"vsubne","⊊":"subne","⊋︀":"vsupne","⊋":"supne","⊍":"cupdot","⊎":"uplus","⊏":"sqsub","⊏̸":"NotSquareSubset","⊐":"sqsup","⊐̸":"NotSquareSuperset","⊑":"sqsube","⋢":"nsqsube","⊒":"sqsupe","⋣":"nsqsupe","⊓":"sqcap","⊓︀":"sqcaps","⊔":"sqcup","⊔︀":"sqcups","⊕":"oplus","⊖":"ominus","⊗":"otimes","⊘":"osol","⊙":"odot","⊚":"ocir","⊛":"oast","⊝":"odash","⊞":"plusb","⊟":"minusb","⊠":"timesb","⊡":"sdotb","⊢":"vdash","⊬":"nvdash","⊣":"dashv","⊤":"top","⊥":"bot","⊧":"models","⊨":"vDash","⊭":"nvDash","⊩":"Vdash","⊮":"nVdash","⊪":"Vvdash","⊫":"VDash","⊯":"nVDash","⊰":"prurel","⊲":"vltri","⋪":"nltri","⊳":"vrtri","⋫":"nrtri","⊴":"ltrie","⋬":"nltrie","⊴⃒":"nvltrie","⊵":"rtrie","⋭":"nrtrie","⊵⃒":"nvrtrie","⊶":"origof","⊷":"imof","⊸":"mumap","⊹":"hercon","⊺":"intcal","⊻":"veebar","⊽":"barvee","⊾":"angrtvb","⊿":"lrtri","⋀":"Wedge","⋁":"Vee","⋂":"xcap","⋃":"xcup","⋄":"diam","⋅":"sdot","⋆":"Star","⋇":"divonx","⋈":"bowtie","⋉":"ltimes","⋊":"rtimes","⋋":"lthree","⋌":"rthree","⋍":"bsime","⋎":"cuvee","⋏":"cuwed","⋐":"Sub","⋑":"Sup","⋒":"Cap","⋓":"Cup","⋔":"fork","⋕":"epar","⋖":"ltdot","⋗":"gtdot","⋘":"Ll","⋘̸":"nLl","⋙":"Gg","⋙̸":"nGg","⋚︀":"lesg","⋚":"leg","⋛":"gel","⋛︀":"gesl","⋞":"cuepr","⋟":"cuesc","⋦":"lnsim","⋧":"gnsim","⋨":"prnsim","⋩":"scnsim","⋮":"vellip","⋯":"ctdot","⋰":"utdot","⋱":"dtdot","⋲":"disin","⋳":"isinsv","⋴":"isins","⋵":"isindot","⋵̸":"notindot","⋶":"notinvc","⋷":"notinvb","⋹":"isinE","⋹̸":"notinE","⋺":"nisd","⋻":"xnis","⋼":"nis","⋽":"notnivc","⋾":"notnivb","⌅":"barwed","⌆":"Barwed","⌌":"drcrop","⌍":"dlcrop","⌎":"urcrop","⌏":"ulcrop","⌐":"bnot","⌒":"profline","⌓":"profsurf","⌕":"telrec","⌖":"target","⌜":"ulcorn","⌝":"urcorn","⌞":"dlcorn","⌟":"drcorn","⌢":"frown","⌣":"smile","⌭":"cylcty","⌮":"profalar","⌶":"topbot","⌽":"ovbar","⌿":"solbar","⍼":"angzarr","⎰":"lmoust","⎱":"rmoust","⎴":"tbrk","⎵":"bbrk","⎶":"bbrktbrk","⏜":"OverParenthesis","⏝":"UnderParenthesis","⏞":"OverBrace","⏟":"UnderBrace","⏢":"trpezium","⏧":"elinters","␣":"blank","─":"boxh","│":"boxv","┌":"boxdr","┐":"boxdl","└":"boxur","┘":"boxul","├":"boxvr","┤":"boxvl","┬":"boxhd","┴":"boxhu","┼":"boxvh","═":"boxH","║":"boxV","╒":"boxdR","╓":"boxDr","╔":"boxDR","╕":"boxdL","╖":"boxDl","╗":"boxDL","╘":"boxuR","╙":"boxUr","╚":"boxUR","╛":"boxuL","╜":"boxUl","╝":"boxUL","╞":"boxvR","╟":"boxVr","╠":"boxVR","╡":"boxvL","╢":"boxVl","╣":"boxVL","╤":"boxHd","╥":"boxhD","╦":"boxHD","╧":"boxHu","╨":"boxhU","╩":"boxHU","╪":"boxvH","╫":"boxVh","╬":"boxVH","▀":"uhblk","▄":"lhblk","█":"block","░":"blk14","▒":"blk12","▓":"blk34","□":"squ","▪":"squf","▫":"EmptyVerySmallSquare","▭":"rect","▮":"marker","▱":"fltns","△":"xutri","▴":"utrif","▵":"utri","▸":"rtrif","▹":"rtri","▽":"xdtri","▾":"dtrif","▿":"dtri","◂":"ltrif","◃":"ltri","◊":"loz","○":"cir","◬":"tridot","◯":"xcirc","◸":"ultri","◹":"urtri","◺":"lltri","◻":"EmptySmallSquare","◼":"FilledSmallSquare","★":"starf","☆":"star","☎":"phone","♀":"female","♂":"male","♠":"spades","♣":"clubs","♥":"hearts","♦":"diams","♪":"sung","✓":"check","✗":"cross","✠":"malt","✶":"sext","❘":"VerticalSeparator","⟈":"bsolhsub","⟉":"suphsol","⟵":"xlarr","⟶":"xrarr","⟷":"xharr","⟸":"xlArr","⟹":"xrArr","⟺":"xhArr","⟼":"xmap","⟿":"dzigrarr","⤂":"nvlArr","⤃":"nvrArr","⤄":"nvHarr","⤅":"Map","⤌":"lbarr","⤍":"rbarr","⤎":"lBarr","⤏":"rBarr","⤐":"RBarr","⤑":"DDotrahd","⤒":"UpArrowBar","⤓":"DownArrowBar","⤖":"Rarrtl","⤙":"latail","⤚":"ratail","⤛":"lAtail","⤜":"rAtail","⤝":"larrfs","⤞":"rarrfs","⤟":"larrbfs","⤠":"rarrbfs","⤣":"nwarhk","⤤":"nearhk","⤥":"searhk","⤦":"swarhk","⤧":"nwnear","⤨":"toea","⤩":"tosa","⤪":"swnwar","⤳":"rarrc","⤳̸":"nrarrc","⤵":"cudarrr","⤶":"ldca","⤷":"rdca","⤸":"cudarrl","⤹":"larrpl","⤼":"curarrm","⤽":"cularrp","⥅":"rarrpl","⥈":"harrcir","⥉":"Uarrocir","⥊":"lurdshar","⥋":"ldrushar","⥎":"LeftRightVector","⥏":"RightUpDownVector","⥐":"DownLeftRightVector","⥑":"LeftUpDownVector","⥒":"LeftVectorBar","⥓":"RightVectorBar","⥔":"RightUpVectorBar","⥕":"RightDownVectorBar","⥖":"DownLeftVectorBar","⥗":"DownRightVectorBar","⥘":"LeftUpVectorBar","⥙":"LeftDownVectorBar","⥚":"LeftTeeVector","⥛":"RightTeeVector","⥜":"RightUpTeeVector","⥝":"RightDownTeeVector","⥞":"DownLeftTeeVector","⥟":"DownRightTeeVector","⥠":"LeftUpTeeVector","⥡":"LeftDownTeeVector","⥢":"lHar","⥣":"uHar","⥤":"rHar","⥥":"dHar","⥦":"luruhar","⥧":"ldrdhar","⥨":"ruluhar","⥩":"rdldhar","⥪":"lharul","⥫":"llhard","⥬":"rharul","⥭":"lrhard","⥮":"udhar","⥯":"duhar","⥰":"RoundImplies","⥱":"erarr","⥲":"simrarr","⥳":"larrsim","⥴":"rarrsim","⥵":"rarrap","⥶":"ltlarr","⥸":"gtrarr","⥹":"subrarr","⥻":"suplarr","⥼":"lfisht","⥽":"rfisht","⥾":"ufisht","⥿":"dfisht","⦚":"vzigzag","⦜":"vangrt","⦝":"angrtvbd","⦤":"ange","⦥":"range","⦦":"dwangle","⦧":"uwangle","⦨":"angmsdaa","⦩":"angmsdab","⦪":"angmsdac","⦫":"angmsdad","⦬":"angmsdae","⦭":"angmsdaf","⦮":"angmsdag","⦯":"angmsdah","⦰":"bemptyv","⦱":"demptyv","⦲":"cemptyv","⦳":"raemptyv","⦴":"laemptyv","⦵":"ohbar","⦶":"omid","⦷":"opar","⦹":"operp","⦻":"olcross","⦼":"odsold","⦾":"olcir","⦿":"ofcir","⧀":"olt","⧁":"ogt","⧂":"cirscir","⧃":"cirE","⧄":"solb","⧅":"bsolb","⧉":"boxbox","⧍":"trisb","⧎":"rtriltri","⧏":"LeftTriangleBar","⧏̸":"NotLeftTriangleBar","⧐":"RightTriangleBar","⧐̸":"NotRightTriangleBar","⧜":"iinfin","⧝":"infintie","⧞":"nvinfin","⧣":"eparsl","⧤":"smeparsl","⧥":"eqvparsl","⧫":"lozf","⧴":"RuleDelayed","⧶":"dsol","⨀":"xodot","⨁":"xoplus","⨂":"xotime","⨄":"xuplus","⨆":"xsqcup","⨍":"fpartint","⨐":"cirfnint","⨑":"awint","⨒":"rppolint","⨓":"scpolint","⨔":"npolint","⨕":"pointint","⨖":"quatint","⨗":"intlarhk","⨢":"pluscir","⨣":"plusacir","⨤":"simplus","⨥":"plusdu","⨦":"plussim","⨧":"plustwo","⨩":"mcomma","⨪":"minusdu","⨭":"loplus","⨮":"roplus","⨯":"Cross","⨰":"timesd","⨱":"timesbar","⨳":"smashp","⨴":"lotimes","⨵":"rotimes","⨶":"otimesas","⨷":"Otimes","⨸":"odiv","⨹":"triplus","⨺":"triminus","⨻":"tritime","⨼":"iprod","⨿":"amalg","⩀":"capdot","⩂":"ncup","⩃":"ncap","⩄":"capand","⩅":"cupor","⩆":"cupcap","⩇":"capcup","⩈":"cupbrcap","⩉":"capbrcup","⩊":"cupcup","⩋":"capcap","⩌":"ccups","⩍":"ccaps","⩐":"ccupssm","⩓":"And","⩔":"Or","⩕":"andand","⩖":"oror","⩗":"orslope","⩘":"andslope","⩚":"andv","⩛":"orv","⩜":"andd","⩝":"ord","⩟":"wedbar","⩦":"sdote","⩪":"simdot","⩭":"congdot","⩭̸":"ncongdot","⩮":"easter","⩯":"apacir","⩰":"apE","⩰̸":"napE","⩱":"eplus","⩲":"pluse","⩳":"Esim","⩷":"eDDot","⩸":"equivDD","⩹":"ltcir","⩺":"gtcir","⩻":"ltquest","⩼":"gtquest","⩽":"les","⩽̸":"nles","⩾":"ges","⩾̸":"nges","⩿":"lesdot","⪀":"gesdot","⪁":"lesdoto","⪂":"gesdoto","⪃":"lesdotor","⪄":"gesdotol","⪅":"lap","⪆":"gap","⪇":"lne","⪈":"gne","⪉":"lnap","⪊":"gnap","⪋":"lEg","⪌":"gEl","⪍":"lsime","⪎":"gsime","⪏":"lsimg","⪐":"gsiml","⪑":"lgE","⪒":"glE","⪓":"lesges","⪔":"gesles","⪕":"els","⪖":"egs","⪗":"elsdot","⪘":"egsdot","⪙":"el","⪚":"eg","⪝":"siml","⪞":"simg","⪟":"simlE","⪠":"simgE","⪡":"LessLess","⪡̸":"NotNestedLessLess","⪢":"GreaterGreater","⪢̸":"NotNestedGreaterGreater","⪤":"glj","⪥":"gla","⪦":"ltcc","⪧":"gtcc","⪨":"lescc","⪩":"gescc","⪪":"smt","⪫":"lat","⪬":"smte","⪬︀":"smtes","⪭":"late","⪭︀":"lates","⪮":"bumpE","⪯":"pre","⪯̸":"npre","⪰":"sce","⪰̸":"nsce","⪳":"prE","⪴":"scE","⪵":"prnE","⪶":"scnE","⪷":"prap","⪸":"scap","⪹":"prnap","⪺":"scnap","⪻":"Pr","⪼":"Sc","⪽":"subdot","⪾":"supdot","⪿":"subplus","⫀":"supplus","⫁":"submult","⫂":"supmult","⫃":"subedot","⫄":"supedot","⫅":"subE","⫅̸":"nsubE","⫆":"supE","⫆̸":"nsupE","⫇":"subsim","⫈":"supsim","⫋︀":"vsubnE","⫋":"subnE","⫌︀":"vsupnE","⫌":"supnE","⫏":"csub","⫐":"csup","⫑":"csube","⫒":"csupe","⫓":"subsup","⫔":"supsub","⫕":"subsub","⫖":"supsup","⫗":"suphsub","⫘":"supdsub","⫙":"forkv","⫚":"topfork","⫛":"mlcp","⫤":"Dashv","⫦":"Vdashl","⫧":"Barv","⫨":"vBar","⫩":"vBarv","⫫":"Vbar","⫬":"Not","⫭":"bNot","⫮":"rnmid","⫯":"cirmid","⫰":"midcir","⫱":"topcir","⫲":"nhpar","⫳":"parsim","⫽":"parsl","⫽⃥":"nparsl","♭":"flat","♮":"natur","♯":"sharp","¤":"curren","¢":"cent",$:"dollar","£":"pound","¥":"yen","€":"euro","¹":"sup1","½":"half","⅓":"frac13","¼":"frac14","⅕":"frac15","⅙":"frac16","⅛":"frac18","²":"sup2","⅔":"frac23","⅖":"frac25","³":"sup3","¾":"frac34","⅗":"frac35","⅜":"frac38","⅘":"frac45","⅚":"frac56","⅝":"frac58","⅞":"frac78","𝒶":"ascr","𝕒":"aopf","𝔞":"afr","𝔸":"Aopf","𝔄":"Afr","𝒜":"Ascr","ª":"ordf","á":"aacute","Á":"Aacute","à":"agrave","À":"Agrave","ă":"abreve","Ă":"Abreve","â":"acirc","Â":"Acirc","å":"aring","Å":"angst","ä":"auml","Ä":"Auml","ã":"atilde","Ã":"Atilde","ą":"aogon","Ą":"Aogon","ā":"amacr","Ā":"Amacr","æ":"aelig","Æ":"AElig","𝒷":"bscr","𝕓":"bopf","𝔟":"bfr","𝔹":"Bopf","ℬ":"Bscr","𝔅":"Bfr","𝔠":"cfr","𝒸":"cscr","𝕔":"copf","ℭ":"Cfr","𝒞":"Cscr","ℂ":"Copf","ć":"cacute","Ć":"Cacute","ĉ":"ccirc","Ĉ":"Ccirc","č":"ccaron","Č":"Ccaron","ċ":"cdot","Ċ":"Cdot","ç":"ccedil","Ç":"Ccedil","℅":"incare","𝔡":"dfr","ⅆ":"dd","𝕕":"dopf","𝒹":"dscr","𝒟":"Dscr","𝔇":"Dfr","ⅅ":"DD","𝔻":"Dopf","ď":"dcaron","Ď":"Dcaron","đ":"dstrok","Đ":"Dstrok","ð":"eth","Ð":"ETH","ⅇ":"ee","ℯ":"escr","𝔢":"efr","𝕖":"eopf","ℰ":"Escr","𝔈":"Efr","𝔼":"Eopf","é":"eacute","É":"Eacute","è":"egrave","È":"Egrave","ê":"ecirc","Ê":"Ecirc","ě":"ecaron","Ě":"Ecaron","ë":"euml","Ë":"Euml","ė":"edot","Ė":"Edot","ę":"eogon","Ę":"Eogon","ē":"emacr","Ē":"Emacr","𝔣":"ffr","𝕗":"fopf","𝒻":"fscr","𝔉":"Ffr","𝔽":"Fopf","ℱ":"Fscr","ff":"fflig","ffi":"ffilig","ffl":"ffllig","fi":"filig",fj:"fjlig","fl":"fllig","ƒ":"fnof","ℊ":"gscr","𝕘":"gopf","𝔤":"gfr","𝒢":"Gscr","𝔾":"Gopf","𝔊":"Gfr","ǵ":"gacute","ğ":"gbreve","Ğ":"Gbreve","ĝ":"gcirc","Ĝ":"Gcirc","ġ":"gdot","Ġ":"Gdot","Ģ":"Gcedil","𝔥":"hfr","ℎ":"planckh","𝒽":"hscr","𝕙":"hopf","ℋ":"Hscr","ℌ":"Hfr","ℍ":"Hopf","ĥ":"hcirc","Ĥ":"Hcirc","ℏ":"hbar","ħ":"hstrok","Ħ":"Hstrok","𝕚":"iopf","𝔦":"ifr","𝒾":"iscr","ⅈ":"ii","𝕀":"Iopf","ℐ":"Iscr","ℑ":"Im","í":"iacute","Í":"Iacute","ì":"igrave","Ì":"Igrave","î":"icirc","Î":"Icirc","ï":"iuml","Ï":"Iuml","ĩ":"itilde","Ĩ":"Itilde","İ":"Idot","į":"iogon","Į":"Iogon","ī":"imacr","Ī":"Imacr","ij":"ijlig","IJ":"IJlig","ı":"imath","𝒿":"jscr","𝕛":"jopf","𝔧":"jfr","𝒥":"Jscr","𝔍":"Jfr","𝕁":"Jopf","ĵ":"jcirc","Ĵ":"Jcirc","ȷ":"jmath","𝕜":"kopf","𝓀":"kscr","𝔨":"kfr","𝒦":"Kscr","𝕂":"Kopf","𝔎":"Kfr","ķ":"kcedil","Ķ":"Kcedil","𝔩":"lfr","𝓁":"lscr","ℓ":"ell","𝕝":"lopf","ℒ":"Lscr","𝔏":"Lfr","𝕃":"Lopf","ĺ":"lacute","Ĺ":"Lacute","ľ":"lcaron","Ľ":"Lcaron","ļ":"lcedil","Ļ":"Lcedil","ł":"lstrok","Ł":"Lstrok","ŀ":"lmidot","Ŀ":"Lmidot","𝔪":"mfr","𝕞":"mopf","𝓂":"mscr","𝔐":"Mfr","𝕄":"Mopf","ℳ":"Mscr","𝔫":"nfr","𝕟":"nopf","𝓃":"nscr","ℕ":"Nopf","𝒩":"Nscr","𝔑":"Nfr","ń":"nacute","Ń":"Nacute","ň":"ncaron","Ň":"Ncaron","ñ":"ntilde","Ñ":"Ntilde","ņ":"ncedil","Ņ":"Ncedil","№":"numero","ŋ":"eng","Ŋ":"ENG","𝕠":"oopf","𝔬":"ofr","ℴ":"oscr","𝒪":"Oscr","𝔒":"Ofr","𝕆":"Oopf","º":"ordm","ó":"oacute","Ó":"Oacute","ò":"ograve","Ò":"Ograve","ô":"ocirc","Ô":"Ocirc","ö":"ouml","Ö":"Ouml","ő":"odblac","Ő":"Odblac","õ":"otilde","Õ":"Otilde","ø":"oslash","Ø":"Oslash","ō":"omacr","Ō":"Omacr","œ":"oelig","Œ":"OElig","𝔭":"pfr","𝓅":"pscr","𝕡":"popf","ℙ":"Popf","𝔓":"Pfr","𝒫":"Pscr","𝕢":"qopf","𝔮":"qfr","𝓆":"qscr","𝒬":"Qscr","𝔔":"Qfr","ℚ":"Qopf","ĸ":"kgreen","𝔯":"rfr","𝕣":"ropf","𝓇":"rscr","ℛ":"Rscr","ℜ":"Re","ℝ":"Ropf","ŕ":"racute","Ŕ":"Racute","ř":"rcaron","Ř":"Rcaron","ŗ":"rcedil","Ŗ":"Rcedil","𝕤":"sopf","𝓈":"sscr","𝔰":"sfr","𝕊":"Sopf","𝔖":"Sfr","𝒮":"Sscr","Ⓢ":"oS","ś":"sacute","Ś":"Sacute","ŝ":"scirc","Ŝ":"Scirc","š":"scaron","Š":"Scaron","ş":"scedil","Ş":"Scedil","ß":"szlig","𝔱":"tfr","𝓉":"tscr","𝕥":"topf","𝒯":"Tscr","𝔗":"Tfr","𝕋":"Topf","ť":"tcaron","Ť":"Tcaron","ţ":"tcedil","Ţ":"Tcedil","™":"trade","ŧ":"tstrok","Ŧ":"Tstrok","𝓊":"uscr","𝕦":"uopf","𝔲":"ufr","𝕌":"Uopf","𝔘":"Ufr","𝒰":"Uscr","ú":"uacute","Ú":"Uacute","ù":"ugrave","Ù":"Ugrave","ŭ":"ubreve","Ŭ":"Ubreve","û":"ucirc","Û":"Ucirc","ů":"uring","Ů":"Uring","ü":"uuml","Ü":"Uuml","ű":"udblac","Ű":"Udblac","ũ":"utilde","Ũ":"Utilde","ų":"uogon","Ų":"Uogon","ū":"umacr","Ū":"Umacr","𝔳":"vfr","𝕧":"vopf","𝓋":"vscr","𝔙":"Vfr","𝕍":"Vopf","𝒱":"Vscr","𝕨":"wopf","𝓌":"wscr","𝔴":"wfr","𝒲":"Wscr","𝕎":"Wopf","𝔚":"Wfr","ŵ":"wcirc","Ŵ":"Wcirc","𝔵":"xfr","𝓍":"xscr","𝕩":"xopf","𝕏":"Xopf","𝔛":"Xfr","𝒳":"Xscr","𝔶":"yfr","𝓎":"yscr","𝕪":"yopf","𝒴":"Yscr","𝔜":"Yfr","𝕐":"Yopf","ý":"yacute","Ý":"Yacute","ŷ":"ycirc","Ŷ":"Ycirc","ÿ":"yuml","Ÿ":"Yuml","𝓏":"zscr","𝔷":"zfr","𝕫":"zopf","ℨ":"Zfr","ℤ":"Zopf","𝒵":"Zscr","ź":"zacute","Ź":"Zacute","ž":"zcaron","Ž":"Zcaron","ż":"zdot","Ż":"Zdot","Ƶ":"imped","þ":"thorn","Þ":"THORN","ʼn":"napos","α":"alpha","Α":"Alpha","β":"beta","Β":"Beta","γ":"gamma","Γ":"Gamma","δ":"delta","Δ":"Delta","ε":"epsi","ϵ":"epsiv","Ε":"Epsilon","ϝ":"gammad","Ϝ":"Gammad","ζ":"zeta","Ζ":"Zeta","η":"eta","Η":"Eta","θ":"theta","ϑ":"thetav","Θ":"Theta","ι":"iota","Ι":"Iota","κ":"kappa","ϰ":"kappav","Κ":"Kappa","λ":"lambda","Λ":"Lambda","μ":"mu","µ":"micro","Μ":"Mu","ν":"nu","Ν":"Nu","ξ":"xi","Ξ":"Xi","ο":"omicron","Ο":"Omicron","π":"pi","ϖ":"piv","Π":"Pi","ρ":"rho","ϱ":"rhov","Ρ":"Rho","σ":"sigma","Σ":"Sigma","ς":"sigmaf","τ":"tau","Τ":"Tau","υ":"upsi","Υ":"Upsilon","ϒ":"Upsi","φ":"phi","ϕ":"phiv","Φ":"Phi","χ":"chi","Χ":"Chi","ψ":"psi","Ψ":"Psi","ω":"omega","Ω":"ohm","а":"acy","А":"Acy","б":"bcy","Б":"Bcy","в":"vcy","В":"Vcy","г":"gcy","Г":"Gcy","ѓ":"gjcy","Ѓ":"GJcy","д":"dcy","Д":"Dcy","ђ":"djcy","Ђ":"DJcy","е":"iecy","Е":"IEcy","ё":"iocy","Ё":"IOcy","є":"jukcy","Є":"Jukcy","ж":"zhcy","Ж":"ZHcy","з":"zcy","З":"Zcy","ѕ":"dscy","Ѕ":"DScy","и":"icy","И":"Icy","і":"iukcy","І":"Iukcy","ї":"yicy","Ї":"YIcy","й":"jcy","Й":"Jcy","ј":"jsercy","Ј":"Jsercy","к":"kcy","К":"Kcy","ќ":"kjcy","Ќ":"KJcy","л":"lcy","Л":"Lcy","љ":"ljcy","Љ":"LJcy","м":"mcy","М":"Mcy","н":"ncy","Н":"Ncy","њ":"njcy","Њ":"NJcy","о":"ocy","О":"Ocy","п":"pcy","П":"Pcy","р":"rcy","Р":"Rcy","с":"scy","С":"Scy","т":"tcy","Т":"Tcy","ћ":"tshcy","Ћ":"TSHcy","у":"ucy","У":"Ucy","ў":"ubrcy","Ў":"Ubrcy","ф":"fcy","Ф":"Fcy","х":"khcy","Х":"KHcy","ц":"tscy","Ц":"TScy","ч":"chcy","Ч":"CHcy","џ":"dzcy","Џ":"DZcy","ш":"shcy","Ш":"SHcy","щ":"shchcy","Щ":"SHCHcy","ъ":"hardcy","Ъ":"HARDcy","ы":"ycy","Ы":"Ycy","ь":"softcy","Ь":"SOFTcy","э":"ecy","Э":"Ecy","ю":"yucy","Ю":"YUcy","я":"yacy","Я":"YAcy","ℵ":"aleph","ℶ":"beth","ℷ":"gimel","ℸ":"daleth"},p=/["&'<>`]/g,d={'"':""","&":"&","'":"'","<":"<",">":">","`":"`"},f=/&#(?:[xX][^a-fA-F0-9]|[^0-9xX])/,b=/[\0-\x08\x0B\x0E-\x1F\x7F-\x9F\uFDD0-\uFDEF\uFFFE\uFFFF]|[\uD83F\uD87F\uD8BF\uD8FF\uD93F\uD97F\uD9BF\uD9FF\uDA3F\uDA7F\uDABF\uDAFF\uDB3F\uDB7F\uDBBF\uDBFF][\uDFFE\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/,A=/&(CounterClockwiseContourIntegral|DoubleLongLeftRightArrow|ClockwiseContourIntegral|NotNestedGreaterGreater|NotSquareSupersetEqual|DiacriticalDoubleAcute|NotRightTriangleEqual|NotSucceedsSlantEqual|NotPrecedesSlantEqual|CloseCurlyDoubleQuote|NegativeVeryThinSpace|DoubleContourIntegral|FilledVerySmallSquare|CapitalDifferentialD|OpenCurlyDoubleQuote|EmptyVerySmallSquare|NestedGreaterGreater|DoubleLongRightArrow|NotLeftTriangleEqual|NotGreaterSlantEqual|ReverseUpEquilibrium|DoubleLeftRightArrow|NotSquareSubsetEqual|NotDoubleVerticalBar|RightArrowLeftArrow|NotGreaterFullEqual|NotRightTriangleBar|SquareSupersetEqual|DownLeftRightVector|DoubleLongLeftArrow|leftrightsquigarrow|LeftArrowRightArrow|NegativeMediumSpace|blacktriangleright|RightDownVectorBar|PrecedesSlantEqual|RightDoubleBracket|SucceedsSlantEqual|NotLeftTriangleBar|RightTriangleEqual|SquareIntersection|RightDownTeeVector|ReverseEquilibrium|NegativeThickSpace|longleftrightarrow|Longleftrightarrow|LongLeftRightArrow|DownRightTeeVector|DownRightVectorBar|GreaterSlantEqual|SquareSubsetEqual|LeftDownVectorBar|LeftDoubleBracket|VerticalSeparator|rightleftharpoons|NotGreaterGreater|NotSquareSuperset|blacktriangleleft|blacktriangledown|NegativeThinSpace|LeftDownTeeVector|NotLessSlantEqual|leftrightharpoons|DoubleUpDownArrow|DoubleVerticalBar|LeftTriangleEqual|FilledSmallSquare|twoheadrightarrow|NotNestedLessLess|DownLeftTeeVector|DownLeftVectorBar|RightAngleBracket|NotTildeFullEqual|NotReverseElement|RightUpDownVector|DiacriticalTilde|NotSucceedsTilde|circlearrowright|NotPrecedesEqual|rightharpoondown|DoubleRightArrow|NotSucceedsEqual|NonBreakingSpace|NotRightTriangle|LessEqualGreater|RightUpTeeVector|LeftAngleBracket|GreaterFullEqual|DownArrowUpArrow|RightUpVectorBar|twoheadleftarrow|GreaterEqualLess|downharpoonright|RightTriangleBar|ntrianglerighteq|NotSupersetEqual|LeftUpDownVector|DiacriticalAcute|rightrightarrows|vartriangleright|UpArrowDownArrow|DiacriticalGrave|UnderParenthesis|EmptySmallSquare|LeftUpVectorBar|leftrightarrows|DownRightVector|downharpoonleft|trianglerighteq|ShortRightArrow|OverParenthesis|DoubleLeftArrow|DoubleDownArrow|NotSquareSubset|bigtriangledown|ntrianglelefteq|UpperRightArrow|curvearrowright|vartriangleleft|NotLeftTriangle|nleftrightarrow|LowerRightArrow|NotHumpDownHump|NotGreaterTilde|rightthreetimes|LeftUpTeeVector|NotGreaterEqual|straightepsilon|LeftTriangleBar|rightsquigarrow|ContourIntegral|rightleftarrows|CloseCurlyQuote|RightDownVector|LeftRightVector|nLeftrightarrow|leftharpoondown|circlearrowleft|SquareSuperset|OpenCurlyQuote|hookrightarrow|HorizontalLine|DiacriticalDot|NotLessGreater|ntriangleright|DoubleRightTee|InvisibleComma|InvisibleTimes|LowerLeftArrow|DownLeftVector|NotSubsetEqual|curvearrowleft|trianglelefteq|NotVerticalBar|TildeFullEqual|downdownarrows|NotGreaterLess|RightTeeVector|ZeroWidthSpace|looparrowright|LongRightArrow|doublebarwedge|ShortLeftArrow|ShortDownArrow|RightVectorBar|GreaterGreater|ReverseElement|rightharpoonup|LessSlantEqual|leftthreetimes|upharpoonright|rightarrowtail|LeftDownVector|Longrightarrow|NestedLessLess|UpperLeftArrow|nshortparallel|leftleftarrows|leftrightarrow|Leftrightarrow|LeftRightArrow|longrightarrow|upharpoonleft|RightArrowBar|ApplyFunction|LeftTeeVector|leftarrowtail|NotEqualTilde|varsubsetneqq|varsupsetneqq|RightTeeArrow|SucceedsEqual|SucceedsTilde|LeftVectorBar|SupersetEqual|hookleftarrow|DifferentialD|VerticalTilde|VeryThinSpace|blacktriangle|bigtriangleup|LessFullEqual|divideontimes|leftharpoonup|UpEquilibrium|ntriangleleft|RightTriangle|measuredangle|shortparallel|longleftarrow|Longleftarrow|LongLeftArrow|DoubleLeftTee|Poincareplane|PrecedesEqual|triangleright|DoubleUpArrow|RightUpVector|fallingdotseq|looparrowleft|PrecedesTilde|NotTildeEqual|NotTildeTilde|smallsetminus|Proportional|triangleleft|triangledown|UnderBracket|NotHumpEqual|exponentiale|ExponentialE|NotLessTilde|HilbertSpace|RightCeiling|blacklozenge|varsupsetneq|HumpDownHump|GreaterEqual|VerticalLine|LeftTeeArrow|NotLessEqual|DownTeeArrow|LeftTriangle|varsubsetneq|Intersection|NotCongruent|DownArrowBar|LeftUpVector|LeftArrowBar|risingdotseq|GreaterTilde|RoundImplies|SquareSubset|ShortUpArrow|NotSuperset|quaternions|precnapprox|backepsilon|preccurlyeq|OverBracket|blacksquare|MediumSpace|VerticalBar|circledcirc|circleddash|CircleMinus|CircleTimes|LessGreater|curlyeqprec|curlyeqsucc|diamondsuit|UpDownArrow|Updownarrow|RuleDelayed|Rrightarrow|updownarrow|RightVector|nRightarrow|nrightarrow|eqslantless|LeftCeiling|Equilibrium|SmallCircle|expectation|NotSucceeds|thickapprox|GreaterLess|SquareUnion|NotPrecedes|NotLessLess|straightphi|succnapprox|succcurlyeq|SubsetEqual|sqsupseteq|Proportion|Laplacetrf|ImaginaryI|supsetneqq|NotGreater|gtreqqless|NotElement|ThickSpace|TildeEqual|TildeTilde|Fouriertrf|rmoustache|EqualTilde|eqslantgtr|UnderBrace|LeftVector|UpArrowBar|nLeftarrow|nsubseteqq|subsetneqq|nsupseteqq|nleftarrow|succapprox|lessapprox|UpTeeArrow|upuparrows|curlywedge|lesseqqgtr|varepsilon|varnothing|RightFloor|complement|CirclePlus|sqsubseteq|Lleftarrow|circledast|RightArrow|Rightarrow|rightarrow|lmoustache|Bernoullis|precapprox|mapstoleft|mapstodown|longmapsto|dotsquare|downarrow|DoubleDot|nsubseteq|supsetneq|leftarrow|nsupseteq|subsetneq|ThinSpace|ngeqslant|subseteqq|HumpEqual|NotSubset|triangleq|NotCupCap|lesseqgtr|heartsuit|TripleDot|Leftarrow|Coproduct|Congruent|varpropto|complexes|gvertneqq|LeftArrow|LessTilde|supseteqq|MinusPlus|CircleDot|nleqslant|NotExists|gtreqless|nparallel|UnionPlus|LeftFloor|checkmark|CenterDot|centerdot|Mellintrf|gtrapprox|bigotimes|OverBrace|spadesuit|therefore|pitchfork|rationals|PlusMinus|Backslash|Therefore|DownBreve|backsimeq|backprime|DownArrow|nshortmid|Downarrow|lvertneqq|eqvparsl|imagline|imagpart|infintie|integers|Integral|intercal|LessLess|Uarrocir|intlarhk|sqsupset|angmsdaf|sqsubset|llcorner|vartheta|cupbrcap|lnapprox|Superset|SuchThat|succnsim|succneqq|angmsdag|biguplus|curlyvee|trpezium|Succeeds|NotTilde|bigwedge|angmsdah|angrtvbd|triminus|cwconint|fpartint|lrcorner|smeparsl|subseteq|urcorner|lurdshar|laemptyv|DDotrahd|approxeq|ldrushar|awconint|mapstoup|backcong|shortmid|triangle|geqslant|gesdotol|timesbar|circledR|circledS|setminus|multimap|naturals|scpolint|ncongdot|RightTee|boxminus|gnapprox|boxtimes|andslope|thicksim|angmsdaa|varsigma|cirfnint|rtriltri|angmsdab|rppolint|angmsdac|barwedge|drbkarow|clubsuit|thetasym|bsolhsub|capbrcup|dzigrarr|doteqdot|DotEqual|dotminus|UnderBar|NotEqual|realpart|otimesas|ulcorner|hksearow|hkswarow|parallel|PartialD|elinters|emptyset|plusacir|bbrktbrk|angmsdad|pointint|bigoplus|angmsdae|Precedes|bigsqcup|varkappa|notindot|supseteq|precneqq|precnsim|profalar|profline|profsurf|leqslant|lesdotor|raemptyv|subplus|notnivb|notnivc|subrarr|zigrarr|vzigzag|submult|subedot|Element|between|cirscir|larrbfs|larrsim|lotimes|lbrksld|lbrkslu|lozenge|ldrdhar|dbkarow|bigcirc|epsilon|simrarr|simplus|ltquest|Epsilon|luruhar|gtquest|maltese|npolint|eqcolon|npreceq|bigodot|ddagger|gtrless|bnequiv|harrcir|ddotseq|equivDD|backsim|demptyv|nsqsube|nsqsupe|Upsilon|nsubset|upsilon|minusdu|nsucceq|swarrow|nsupset|coloneq|searrow|boxplus|napprox|natural|asympeq|alefsym|congdot|nearrow|bigstar|diamond|supplus|tritime|LeftTee|nvinfin|triplus|NewLine|nvltrie|nvrtrie|nwarrow|nexists|Diamond|ruluhar|Implies|supmult|angzarr|suplarr|suphsub|questeq|because|digamma|Because|olcross|bemptyv|omicron|Omicron|rotimes|NoBreak|intprod|angrtvb|orderof|uwangle|suphsol|lesdoto|orslope|DownTee|realine|cudarrl|rdldhar|OverBar|supedot|lessdot|supdsub|topfork|succsim|rbrkslu|rbrksld|pertenk|cudarrr|isindot|planckh|lessgtr|pluscir|gesdoto|plussim|plustwo|lesssim|cularrp|rarrsim|Cayleys|notinva|notinvb|notinvc|UpArrow|Uparrow|uparrow|NotLess|dwangle|precsim|Product|curarrm|Cconint|dotplus|rarrbfs|ccupssm|Cedilla|cemptyv|notniva|quatint|frac35|frac38|frac45|frac56|frac58|frac78|tridot|xoplus|gacute|gammad|Gammad|lfisht|lfloor|bigcup|sqsupe|gbreve|Gbreve|lharul|sqsube|sqcups|Gcedil|apacir|llhard|lmidot|Lmidot|lmoust|andand|sqcaps|approx|Abreve|spades|circeq|tprime|divide|topcir|Assign|topbot|gesdot|divonx|xuplus|timesd|gesles|atilde|solbar|SOFTcy|loplus|timesb|lowast|lowbar|dlcorn|dlcrop|softcy|dollar|lparlt|thksim|lrhard|Atilde|lsaquo|smashp|bigvee|thinsp|wreath|bkarow|lsquor|lstrok|Lstrok|lthree|ltimes|ltlarr|DotDot|simdot|ltrPar|weierp|xsqcup|angmsd|sigmav|sigmaf|zeetrf|Zcaron|zcaron|mapsto|vsupne|thetav|cirmid|marker|mcomma|Zacute|vsubnE|there4|gtlPar|vsubne|bottom|gtrarr|SHCHcy|shchcy|midast|midcir|middot|minusb|minusd|gtrdot|bowtie|sfrown|mnplus|models|colone|seswar|Colone|mstpos|searhk|gtrsim|nacute|Nacute|boxbox|telrec|hairsp|Tcedil|nbumpe|scnsim|ncaron|Ncaron|ncedil|Ncedil|hamilt|Scedil|nearhk|hardcy|HARDcy|tcedil|Tcaron|commat|nequiv|nesear|tcaron|target|hearts|nexist|varrho|scedil|Scaron|scaron|hellip|Sacute|sacute|hercon|swnwar|compfn|rtimes|rthree|rsquor|rsaquo|zacute|wedgeq|homtht|barvee|barwed|Barwed|rpargt|horbar|conint|swarhk|roplus|nltrie|hslash|hstrok|Hstrok|rmoust|Conint|bprime|hybull|hyphen|iacute|Iacute|supsup|supsub|supsim|varphi|coprod|brvbar|agrave|Supset|supset|igrave|Igrave|notinE|Agrave|iiiint|iinfin|copysr|wedbar|Verbar|vangrt|becaus|incare|verbar|inodot|bullet|drcorn|intcal|drcrop|cularr|vellip|Utilde|bumpeq|cupcap|dstrok|Dstrok|CupCap|cupcup|cupdot|eacute|Eacute|supdot|iquest|easter|ecaron|Ecaron|ecolon|isinsv|utilde|itilde|Itilde|curarr|succeq|Bumpeq|cacute|ulcrop|nparsl|Cacute|nprcue|egrave|Egrave|nrarrc|nrarrw|subsup|subsub|nrtrie|jsercy|nsccue|Jsercy|kappav|kcedil|Kcedil|subsim|ulcorn|nsimeq|egsdot|veebar|kgreen|capand|elsdot|Subset|subset|curren|aacute|lacute|Lacute|emptyv|ntilde|Ntilde|lagran|lambda|Lambda|capcap|Ugrave|langle|subdot|emsp13|numero|emsp14|nvdash|nvDash|nVdash|nVDash|ugrave|ufisht|nvHarr|larrfs|nvlArr|larrhk|larrlp|larrpl|nvrArr|Udblac|nwarhk|larrtl|nwnear|oacute|Oacute|latail|lAtail|sstarf|lbrace|odblac|Odblac|lbrack|udblac|odsold|eparsl|lcaron|Lcaron|ograve|Ograve|lcedil|Lcedil|Aacute|ssmile|ssetmn|squarf|ldquor|capcup|ominus|cylcty|rharul|eqcirc|dagger|rfloor|rfisht|Dagger|daleth|equals|origof|capdot|equest|dcaron|Dcaron|rdquor|oslash|Oslash|otilde|Otilde|otimes|Otimes|urcrop|Ubreve|ubreve|Yacute|Uacute|uacute|Rcedil|rcedil|urcorn|parsim|Rcaron|Vdashl|rcaron|Tstrok|percnt|period|permil|Exists|yacute|rbrack|rbrace|phmmat|ccaron|Ccaron|planck|ccedil|plankv|tstrok|female|plusdo|plusdu|ffilig|plusmn|ffllig|Ccedil|rAtail|dfisht|bernou|ratail|Rarrtl|rarrtl|angsph|rarrpl|rarrlp|rarrhk|xwedge|xotime|forall|ForAll|Vvdash|vsupnE|preceq|bigcap|frac12|frac13|frac14|primes|rarrfs|prnsim|frac15|Square|frac16|square|lesdot|frac18|frac23|propto|prurel|rarrap|rangle|puncsp|frac25|Racute|qprime|racute|lesges|frac34|abreve|AElig|eqsim|utdot|setmn|urtri|Equal|Uring|seArr|uring|searr|dashv|Dashv|mumap|nabla|iogon|Iogon|sdote|sdotb|scsim|napid|napos|equiv|natur|Acirc|dblac|erarr|nbump|iprod|erDot|ucirc|awint|esdot|angrt|ncong|isinE|scnap|Scirc|scirc|ndash|isins|Ubrcy|nearr|neArr|isinv|nedot|ubrcy|acute|Ycirc|iukcy|Iukcy|xutri|nesim|caret|jcirc|Jcirc|caron|twixt|ddarr|sccue|exist|jmath|sbquo|ngeqq|angst|ccaps|lceil|ngsim|UpTee|delta|Delta|rtrif|nharr|nhArr|nhpar|rtrie|jukcy|Jukcy|kappa|rsquo|Kappa|nlarr|nlArr|TSHcy|rrarr|aogon|Aogon|fflig|xrarr|tshcy|ccirc|nleqq|filig|upsih|nless|dharl|nlsim|fjlig|ropar|nltri|dharr|robrk|roarr|fllig|fltns|roang|rnmid|subnE|subne|lAarr|trisb|Ccirc|acirc|ccups|blank|VDash|forkv|Vdash|langd|cedil|blk12|blk14|laquo|strns|diams|notin|vDash|larrb|blk34|block|disin|uplus|vdash|vBarv|aelig|starf|Wedge|check|xrArr|lates|lbarr|lBarr|notni|lbbrk|bcong|frasl|lbrke|frown|vrtri|vprop|vnsup|gamma|Gamma|wedge|xodot|bdquo|srarr|doteq|ldquo|boxdl|boxdL|gcirc|Gcirc|boxDl|boxDL|boxdr|boxdR|boxDr|TRADE|trade|rlhar|boxDR|vnsub|npart|vltri|rlarr|boxhd|boxhD|nprec|gescc|nrarr|nrArr|boxHd|boxHD|boxhu|boxhU|nrtri|boxHu|clubs|boxHU|times|colon|Colon|gimel|xlArr|Tilde|nsime|tilde|nsmid|nspar|THORN|thorn|xlarr|nsube|nsubE|thkap|xhArr|comma|nsucc|boxul|boxuL|nsupe|nsupE|gneqq|gnsim|boxUl|boxUL|grave|boxur|boxuR|boxUr|boxUR|lescc|angle|bepsi|boxvh|varpi|boxvH|numsp|Theta|gsime|gsiml|theta|boxVh|boxVH|boxvl|gtcir|gtdot|boxvL|boxVl|boxVL|crarr|cross|Cross|nvsim|boxvr|nwarr|nwArr|sqsup|dtdot|Uogon|lhard|lharu|dtrif|ocirc|Ocirc|lhblk|duarr|odash|sqsub|Hacek|sqcup|llarr|duhar|oelig|OElig|ofcir|boxvR|uogon|lltri|boxVr|csube|uuarr|ohbar|csupe|ctdot|olarr|olcir|harrw|oline|sqcap|omacr|Omacr|omega|Omega|boxVR|aleph|lneqq|lnsim|loang|loarr|rharu|lobrk|hcirc|operp|oplus|rhard|Hcirc|orarr|Union|order|ecirc|Ecirc|cuepr|szlig|cuesc|breve|reals|eDDot|Breve|hoarr|lopar|utrif|rdquo|Umacr|umacr|efDot|swArr|ultri|alpha|rceil|ovbar|swarr|Wcirc|wcirc|smtes|smile|bsemi|lrarr|aring|parsl|lrhar|bsime|uhblk|lrtri|cupor|Aring|uharr|uharl|slarr|rbrke|bsolb|lsime|rbbrk|RBarr|lsimg|phone|rBarr|rbarr|icirc|lsquo|Icirc|emacr|Emacr|ratio|simne|plusb|simlE|simgE|simeq|pluse|ltcir|ltdot|empty|xharr|xdtri|iexcl|Alpha|ltrie|rarrw|pound|ltrif|xcirc|bumpe|prcue|bumpE|asymp|amacr|cuvee|Sigma|sigma|iiint|udhar|iiota|ijlig|IJlig|supnE|imacr|Imacr|prime|Prime|image|prnap|eogon|Eogon|rarrc|mdash|mDDot|cuwed|imath|supne|imped|Amacr|udarr|prsim|micro|rarrb|cwint|raquo|infin|eplus|range|rangd|Ucirc|radic|minus|amalg|veeeq|rAarr|epsiv|ycirc|quest|sharp|quot|zwnj|Qscr|race|qscr|Qopf|qopf|qint|rang|Rang|Zscr|zscr|Zopf|zopf|rarr|rArr|Rarr|Pscr|pscr|prop|prod|prnE|prec|ZHcy|zhcy|prap|Zeta|zeta|Popf|popf|Zdot|plus|zdot|Yuml|yuml|phiv|YUcy|yucy|Yscr|yscr|perp|Yopf|yopf|part|para|YIcy|Ouml|rcub|yicy|YAcy|rdca|ouml|osol|Oscr|rdsh|yacy|real|oscr|xvee|andd|rect|andv|Xscr|oror|ordm|ordf|xscr|ange|aopf|Aopf|rHar|Xopf|opar|Oopf|xopf|xnis|rhov|oopf|omid|xmap|oint|apid|apos|ogon|ascr|Ascr|odot|odiv|xcup|xcap|ocir|oast|nvlt|nvle|nvgt|nvge|nvap|Wscr|wscr|auml|ntlg|ntgl|nsup|nsub|nsim|Nscr|nscr|nsce|Wopf|ring|npre|wopf|npar|Auml|Barv|bbrk|Nopf|nopf|nmid|nLtv|beta|ropf|Ropf|Beta|beth|nles|rpar|nleq|bnot|bNot|nldr|NJcy|rscr|Rscr|Vscr|vscr|rsqb|njcy|bopf|nisd|Bopf|rtri|Vopf|nGtv|ngtr|vopf|boxh|boxH|boxv|nges|ngeq|boxV|bscr|scap|Bscr|bsim|Vert|vert|bsol|bull|bump|caps|cdot|ncup|scnE|ncap|nbsp|napE|Cdot|cent|sdot|Vbar|nang|vBar|chcy|Mscr|mscr|sect|semi|CHcy|Mopf|mopf|sext|circ|cire|mldr|mlcp|cirE|comp|shcy|SHcy|vArr|varr|cong|copf|Copf|copy|COPY|malt|male|macr|lvnE|cscr|ltri|sime|ltcc|simg|Cscr|siml|csub|Uuml|lsqb|lsim|uuml|csup|Lscr|lscr|utri|smid|lpar|cups|smte|lozf|darr|Lopf|Uscr|solb|lopf|sopf|Sopf|lneq|uscr|spar|dArr|lnap|Darr|dash|Sqrt|LJcy|ljcy|lHar|dHar|Upsi|upsi|diam|lesg|djcy|DJcy|leqq|dopf|Dopf|dscr|Dscr|dscy|ldsh|ldca|squf|DScy|sscr|Sscr|dsol|lcub|late|star|Star|Uopf|Larr|lArr|larr|uopf|dtri|dzcy|sube|subE|Lang|lang|Kscr|kscr|Kopf|kopf|KJcy|kjcy|KHcy|khcy|DZcy|ecir|edot|eDot|Jscr|jscr|succ|Jopf|jopf|Edot|uHar|emsp|ensp|Iuml|iuml|eopf|isin|Iscr|iscr|Eopf|epar|sung|epsi|escr|sup1|sup2|sup3|Iota|iota|supe|supE|Iopf|iopf|IOcy|iocy|Escr|esim|Esim|imof|Uarr|QUOT|uArr|uarr|euml|IEcy|iecy|Idot|Euml|euro|excl|Hscr|hscr|Hopf|hopf|TScy|tscy|Tscr|hbar|tscr|flat|tbrk|fnof|hArr|harr|half|fopf|Fopf|tdot|gvnE|fork|trie|gtcc|fscr|Fscr|gdot|gsim|Gscr|gscr|Gopf|gopf|gneq|Gdot|tosa|gnap|Topf|topf|geqq|toea|GJcy|gjcy|tint|gesl|mid|Sfr|ggg|top|ges|gla|glE|glj|geq|gne|gEl|gel|gnE|Gcy|gcy|gap|Tfr|tfr|Tcy|tcy|Hat|Tau|Ffr|tau|Tab|hfr|Hfr|ffr|Fcy|fcy|icy|Icy|iff|ETH|eth|ifr|Ifr|Eta|eta|int|Int|Sup|sup|ucy|Ucy|Sum|sum|jcy|ENG|ufr|Ufr|eng|Jcy|jfr|els|ell|egs|Efr|efr|Jfr|uml|kcy|Kcy|Ecy|ecy|kfr|Kfr|lap|Sub|sub|lat|lcy|Lcy|leg|Dot|dot|lEg|leq|les|squ|div|die|lfr|Lfr|lgE|Dfr|dfr|Del|deg|Dcy|dcy|lne|lnE|sol|loz|smt|Cup|lrm|cup|lsh|Lsh|sim|shy|map|Map|mcy|Mcy|mfr|Mfr|mho|gfr|Gfr|sfr|cir|Chi|chi|nap|Cfr|vcy|Vcy|cfr|Scy|scy|ncy|Ncy|vee|Vee|Cap|cap|nfr|scE|sce|Nfr|nge|ngE|nGg|vfr|Vfr|ngt|bot|nGt|nis|niv|Rsh|rsh|nle|nlE|bne|Bfr|bfr|nLl|nlt|nLt|Bcy|bcy|not|Not|rlm|wfr|Wfr|npr|nsc|num|ocy|ast|Ocy|ofr|xfr|Xfr|Ofr|ogt|ohm|apE|olt|Rho|ape|rho|Rfr|rfr|ord|REG|ang|reg|orv|And|and|AMP|Rcy|amp|Afr|ycy|Ycy|yen|yfr|Yfr|rcy|par|pcy|Pcy|pfr|Pfr|phi|Phi|afr|Acy|acy|zcy|Zcy|piv|acE|acd|zfr|Zfr|pre|prE|psi|Psi|qfr|Qfr|zwj|Or|ge|Gg|gt|gg|el|oS|lt|Lt|LT|Re|lg|gl|eg|ne|Im|it|le|DD|wp|wr|nu|Nu|dd|lE|Sc|sc|pi|Pi|ee|af|ll|Ll|rx|gE|xi|pm|Xi|ic|pr|Pr|in|ni|mp|mu|ac|Mu|or|ap|Gt|GT|ii);|&(Aacute|Agrave|Atilde|Ccedil|Eacute|Egrave|Iacute|Igrave|Ntilde|Oacute|Ograve|Oslash|Otilde|Uacute|Ugrave|Yacute|aacute|agrave|atilde|brvbar|ccedil|curren|divide|eacute|egrave|frac12|frac14|frac34|iacute|igrave|iquest|middot|ntilde|oacute|ograve|oslash|otilde|plusmn|uacute|ugrave|yacute|AElig|Acirc|Aring|Ecirc|Icirc|Ocirc|THORN|Ucirc|acirc|acute|aelig|aring|cedil|ecirc|icirc|iexcl|laquo|micro|ocirc|pound|raquo|szlig|thorn|times|ucirc|Auml|COPY|Euml|Iuml|Ouml|QUOT|Uuml|auml|cent|copy|euml|iuml|macr|nbsp|ordf|ordm|ouml|para|quot|sect|sup1|sup2|sup3|uuml|yuml|AMP|ETH|REG|amp|deg|eth|not|reg|shy|uml|yen|GT|LT|gt|lt)(?!;)([=a-zA-Z0-9]?)|&#([0-9]+)(;?)|&#[xX]([a-fA-F0-9]+)(;?)|&([0-9a-zA-Z]+)/g,y={aacute:"á",Aacute:"Á",abreve:"ă",Abreve:"Ă",ac:"∾",acd:"∿",acE:"∾̳",acirc:"â",Acirc:"Â",acute:"´",acy:"а",Acy:"А",aelig:"æ",AElig:"Æ",af:"⁡",afr:"𝔞",Afr:"𝔄",agrave:"à",Agrave:"À",alefsym:"ℵ",aleph:"ℵ",alpha:"α",Alpha:"Α",amacr:"ā",Amacr:"Ā",amalg:"⨿",amp:"&",AMP:"&",and:"∧",And:"⩓",andand:"⩕",andd:"⩜",andslope:"⩘",andv:"⩚",ang:"∠",ange:"⦤",angle:"∠",angmsd:"∡",angmsdaa:"⦨",angmsdab:"⦩",angmsdac:"⦪",angmsdad:"⦫",angmsdae:"⦬",angmsdaf:"⦭",angmsdag:"⦮",angmsdah:"⦯",angrt:"∟",angrtvb:"⊾",angrtvbd:"⦝",angsph:"∢",angst:"Å",angzarr:"⍼",aogon:"ą",Aogon:"Ą",aopf:"𝕒",Aopf:"𝔸",ap:"≈",apacir:"⩯",ape:"≊",apE:"⩰",apid:"≋",apos:"'",ApplyFunction:"⁡",approx:"≈",approxeq:"≊",aring:"å",Aring:"Å",ascr:"𝒶",Ascr:"𝒜",Assign:"≔",ast:"*",asymp:"≈",asympeq:"≍",atilde:"ã",Atilde:"Ã",auml:"ä",Auml:"Ä",awconint:"∳",awint:"⨑",backcong:"≌",backepsilon:"϶",backprime:"‵",backsim:"∽",backsimeq:"⋍",Backslash:"∖",Barv:"⫧",barvee:"⊽",barwed:"⌅",Barwed:"⌆",barwedge:"⌅",bbrk:"⎵",bbrktbrk:"⎶",bcong:"≌",bcy:"б",Bcy:"Б",bdquo:"„",becaus:"∵",because:"∵",Because:"∵",bemptyv:"⦰",bepsi:"϶",bernou:"ℬ",Bernoullis:"ℬ",beta:"β",Beta:"Β",beth:"ℶ",between:"≬",bfr:"𝔟",Bfr:"𝔅",bigcap:"⋂",bigcirc:"◯",bigcup:"⋃",bigodot:"⨀",bigoplus:"⨁",bigotimes:"⨂",bigsqcup:"⨆",bigstar:"★",bigtriangledown:"▽",bigtriangleup:"△",biguplus:"⨄",bigvee:"⋁",bigwedge:"⋀",bkarow:"⤍",blacklozenge:"⧫",blacksquare:"▪",blacktriangle:"▴",blacktriangledown:"▾",blacktriangleleft:"◂",blacktriangleright:"▸",blank:"␣",blk12:"▒",blk14:"░",blk34:"▓",block:"█",bne:"=⃥",bnequiv:"≡⃥",bnot:"⌐",bNot:"⫭",bopf:"𝕓",Bopf:"𝔹",bot:"⊥",bottom:"⊥",bowtie:"⋈",boxbox:"⧉",boxdl:"┐",boxdL:"╕",boxDl:"╖",boxDL:"╗",boxdr:"┌",boxdR:"╒",boxDr:"╓",boxDR:"╔",boxh:"─",boxH:"═",boxhd:"┬",boxhD:"╥",boxHd:"╤",boxHD:"╦",boxhu:"┴",boxhU:"╨",boxHu:"╧",boxHU:"╩",boxminus:"⊟",boxplus:"⊞",boxtimes:"⊠",boxul:"┘",boxuL:"╛",boxUl:"╜",boxUL:"╝",boxur:"└",boxuR:"╘",boxUr:"╙",boxUR:"╚",boxv:"│",boxV:"║",boxvh:"┼",boxvH:"╪",boxVh:"╫",boxVH:"╬",boxvl:"┤",boxvL:"╡",boxVl:"╢",boxVL:"╣",boxvr:"├",boxvR:"╞",boxVr:"╟",boxVR:"╠",bprime:"‵",breve:"˘",Breve:"˘",brvbar:"¦",bscr:"𝒷",Bscr:"ℬ",bsemi:"⁏",bsim:"∽",bsime:"⋍",bsol:"\\",bsolb:"⧅",bsolhsub:"⟈",bull:"•",bullet:"•",bump:"≎",bumpe:"≏",bumpE:"⪮",bumpeq:"≏",Bumpeq:"≎",cacute:"ć",Cacute:"Ć",cap:"∩",Cap:"⋒",capand:"⩄",capbrcup:"⩉",capcap:"⩋",capcup:"⩇",capdot:"⩀",CapitalDifferentialD:"ⅅ",caps:"∩︀",caret:"⁁",caron:"ˇ",Cayleys:"ℭ",ccaps:"⩍",ccaron:"č",Ccaron:"Č",ccedil:"ç",Ccedil:"Ç",ccirc:"ĉ",Ccirc:"Ĉ",Cconint:"∰",ccups:"⩌",ccupssm:"⩐",cdot:"ċ",Cdot:"Ċ",cedil:"¸",Cedilla:"¸",cemptyv:"⦲",cent:"¢",centerdot:"·",CenterDot:"·",cfr:"𝔠",Cfr:"ℭ",chcy:"ч",CHcy:"Ч",check:"✓",checkmark:"✓",chi:"χ",Chi:"Χ",cir:"○",circ:"ˆ",circeq:"≗",circlearrowleft:"↺",circlearrowright:"↻",circledast:"⊛",circledcirc:"⊚",circleddash:"⊝",CircleDot:"⊙",circledR:"®",circledS:"Ⓢ",CircleMinus:"⊖",CirclePlus:"⊕",CircleTimes:"⊗",cire:"≗",cirE:"⧃",cirfnint:"⨐",cirmid:"⫯",cirscir:"⧂",ClockwiseContourIntegral:"∲",CloseCurlyDoubleQuote:"”",CloseCurlyQuote:"’",clubs:"♣",clubsuit:"♣",colon:":",Colon:"∷",colone:"≔",Colone:"⩴",coloneq:"≔",comma:",",commat:"@",comp:"∁",compfn:"∘",complement:"∁",complexes:"ℂ",cong:"≅",congdot:"⩭",Congruent:"≡",conint:"∮",Conint:"∯",ContourIntegral:"∮",copf:"𝕔",Copf:"ℂ",coprod:"∐",Coproduct:"∐",copy:"©",COPY:"©",copysr:"℗",CounterClockwiseContourIntegral:"∳",crarr:"↵",cross:"✗",Cross:"⨯",cscr:"𝒸",Cscr:"𝒞",csub:"⫏",csube:"⫑",csup:"⫐",csupe:"⫒",ctdot:"⋯",cudarrl:"⤸",cudarrr:"⤵",cuepr:"⋞",cuesc:"⋟",cularr:"↶",cularrp:"⤽",cup:"∪",Cup:"⋓",cupbrcap:"⩈",cupcap:"⩆",CupCap:"≍",cupcup:"⩊",cupdot:"⊍",cupor:"⩅",cups:"∪︀",curarr:"↷",curarrm:"⤼",curlyeqprec:"⋞",curlyeqsucc:"⋟",curlyvee:"⋎",curlywedge:"⋏",curren:"¤",curvearrowleft:"↶",curvearrowright:"↷",cuvee:"⋎",cuwed:"⋏",cwconint:"∲",cwint:"∱",cylcty:"⌭",dagger:"†",Dagger:"‡",daleth:"ℸ",darr:"↓",dArr:"⇓",Darr:"↡",dash:"‐",dashv:"⊣",Dashv:"⫤",dbkarow:"⤏",dblac:"˝",dcaron:"ď",Dcaron:"Ď",dcy:"д",Dcy:"Д",dd:"ⅆ",DD:"ⅅ",ddagger:"‡",ddarr:"⇊",DDotrahd:"⤑",ddotseq:"⩷",deg:"°",Del:"∇",delta:"δ",Delta:"Δ",demptyv:"⦱",dfisht:"⥿",dfr:"𝔡",Dfr:"𝔇",dHar:"⥥",dharl:"⇃",dharr:"⇂",DiacriticalAcute:"´",DiacriticalDot:"˙",DiacriticalDoubleAcute:"˝",DiacriticalGrave:"`",DiacriticalTilde:"˜",diam:"⋄",diamond:"⋄",Diamond:"⋄",diamondsuit:"♦",diams:"♦",die:"¨",DifferentialD:"ⅆ",digamma:"ϝ",disin:"⋲",div:"÷",divide:"÷",divideontimes:"⋇",divonx:"⋇",djcy:"ђ",DJcy:"Ђ",dlcorn:"⌞",dlcrop:"⌍",dollar:"$",dopf:"𝕕",Dopf:"𝔻",dot:"˙",Dot:"¨",DotDot:"⃜",doteq:"≐",doteqdot:"≑",DotEqual:"≐",dotminus:"∸",dotplus:"∔",dotsquare:"⊡",doublebarwedge:"⌆",DoubleContourIntegral:"∯",DoubleDot:"¨",DoubleDownArrow:"⇓",DoubleLeftArrow:"⇐",DoubleLeftRightArrow:"⇔",DoubleLeftTee:"⫤",DoubleLongLeftArrow:"⟸",DoubleLongLeftRightArrow:"⟺",DoubleLongRightArrow:"⟹",DoubleRightArrow:"⇒",DoubleRightTee:"⊨",DoubleUpArrow:"⇑",DoubleUpDownArrow:"⇕",DoubleVerticalBar:"∥",downarrow:"↓",Downarrow:"⇓",DownArrow:"↓",DownArrowBar:"⤓",DownArrowUpArrow:"⇵",DownBreve:"̑",downdownarrows:"⇊",downharpoonleft:"⇃",downharpoonright:"⇂",DownLeftRightVector:"⥐",DownLeftTeeVector:"⥞",DownLeftVector:"↽",DownLeftVectorBar:"⥖",DownRightTeeVector:"⥟",DownRightVector:"⇁",DownRightVectorBar:"⥗",DownTee:"⊤",DownTeeArrow:"↧",drbkarow:"⤐",drcorn:"⌟",drcrop:"⌌",dscr:"𝒹",Dscr:"𝒟",dscy:"ѕ",DScy:"Ѕ",dsol:"⧶",dstrok:"đ",Dstrok:"Đ",dtdot:"⋱",dtri:"▿",dtrif:"▾",duarr:"⇵",duhar:"⥯",dwangle:"⦦",dzcy:"џ",DZcy:"Џ",dzigrarr:"⟿",eacute:"é",Eacute:"É",easter:"⩮",ecaron:"ě",Ecaron:"Ě",ecir:"≖",ecirc:"ê",Ecirc:"Ê",ecolon:"≕",ecy:"э",Ecy:"Э",eDDot:"⩷",edot:"ė",eDot:"≑",Edot:"Ė",ee:"ⅇ",efDot:"≒",efr:"𝔢",Efr:"𝔈",eg:"⪚",egrave:"è",Egrave:"È",egs:"⪖",egsdot:"⪘",el:"⪙",Element:"∈",elinters:"⏧",ell:"ℓ",els:"⪕",elsdot:"⪗",emacr:"ē",Emacr:"Ē",empty:"∅",emptyset:"∅",EmptySmallSquare:"◻",emptyv:"∅",EmptyVerySmallSquare:"▫",emsp:" ",emsp13:" ",emsp14:" ",eng:"ŋ",ENG:"Ŋ",ensp:" ",eogon:"ę",Eogon:"Ę",eopf:"𝕖",Eopf:"𝔼",epar:"⋕",eparsl:"⧣",eplus:"⩱",epsi:"ε",epsilon:"ε",Epsilon:"Ε",epsiv:"ϵ",eqcirc:"≖",eqcolon:"≕",eqsim:"≂",eqslantgtr:"⪖",eqslantless:"⪕",Equal:"⩵",equals:"=",EqualTilde:"≂",equest:"≟",Equilibrium:"⇌",equiv:"≡",equivDD:"⩸",eqvparsl:"⧥",erarr:"⥱",erDot:"≓",escr:"ℯ",Escr:"ℰ",esdot:"≐",esim:"≂",Esim:"⩳",eta:"η",Eta:"Η",eth:"ð",ETH:"Ð",euml:"ë",Euml:"Ë",euro:"€",excl:"!",exist:"∃",Exists:"∃",expectation:"ℰ",exponentiale:"ⅇ",ExponentialE:"ⅇ",fallingdotseq:"≒",fcy:"ф",Fcy:"Ф",female:"♀",ffilig:"ffi",fflig:"ff",ffllig:"ffl",ffr:"𝔣",Ffr:"𝔉",filig:"fi",FilledSmallSquare:"◼",FilledVerySmallSquare:"▪",fjlig:"fj",flat:"♭",fllig:"fl",fltns:"▱",fnof:"ƒ",fopf:"𝕗",Fopf:"𝔽",forall:"∀",ForAll:"∀",fork:"⋔",forkv:"⫙",Fouriertrf:"ℱ",fpartint:"⨍",frac12:"½",frac13:"⅓",frac14:"¼",frac15:"⅕",frac16:"⅙",frac18:"⅛",frac23:"⅔",frac25:"⅖",frac34:"¾",frac35:"⅗",frac38:"⅜",frac45:"⅘",frac56:"⅚",frac58:"⅝",frac78:"⅞",frasl:"⁄",frown:"⌢",fscr:"𝒻",Fscr:"ℱ",gacute:"ǵ",gamma:"γ",Gamma:"Γ",gammad:"ϝ",Gammad:"Ϝ",gap:"⪆",gbreve:"ğ",Gbreve:"Ğ",Gcedil:"Ģ",gcirc:"ĝ",Gcirc:"Ĝ",gcy:"г",Gcy:"Г",gdot:"ġ",Gdot:"Ġ",ge:"≥",gE:"≧",gel:"⋛",gEl:"⪌",geq:"≥",geqq:"≧",geqslant:"⩾",ges:"⩾",gescc:"⪩",gesdot:"⪀",gesdoto:"⪂",gesdotol:"⪄",gesl:"⋛︀",gesles:"⪔",gfr:"𝔤",Gfr:"𝔊",gg:"≫",Gg:"⋙",ggg:"⋙",gimel:"ℷ",gjcy:"ѓ",GJcy:"Ѓ",gl:"≷",gla:"⪥",glE:"⪒",glj:"⪤",gnap:"⪊",gnapprox:"⪊",gne:"⪈",gnE:"≩",gneq:"⪈",gneqq:"≩",gnsim:"⋧",gopf:"𝕘",Gopf:"𝔾",grave:"`",GreaterEqual:"≥",GreaterEqualLess:"⋛",GreaterFullEqual:"≧",GreaterGreater:"⪢",GreaterLess:"≷",GreaterSlantEqual:"⩾",GreaterTilde:"≳",gscr:"ℊ",Gscr:"𝒢",gsim:"≳",gsime:"⪎",gsiml:"⪐",gt:">",Gt:"≫",GT:">",gtcc:"⪧",gtcir:"⩺",gtdot:"⋗",gtlPar:"⦕",gtquest:"⩼",gtrapprox:"⪆",gtrarr:"⥸",gtrdot:"⋗",gtreqless:"⋛",gtreqqless:"⪌",gtrless:"≷",gtrsim:"≳",gvertneqq:"≩︀",gvnE:"≩︀",Hacek:"ˇ",hairsp:" ",half:"½",hamilt:"ℋ",hardcy:"ъ",HARDcy:"Ъ",harr:"↔",hArr:"⇔",harrcir:"⥈",harrw:"↭",Hat:"^",hbar:"ℏ",hcirc:"ĥ",Hcirc:"Ĥ",hearts:"♥",heartsuit:"♥",hellip:"…",hercon:"⊹",hfr:"𝔥",Hfr:"ℌ",HilbertSpace:"ℋ",hksearow:"⤥",hkswarow:"⤦",hoarr:"⇿",homtht:"∻",hookleftarrow:"↩",hookrightarrow:"↪",hopf:"𝕙",Hopf:"ℍ",horbar:"―",HorizontalLine:"─",hscr:"𝒽",Hscr:"ℋ",hslash:"ℏ",hstrok:"ħ",Hstrok:"Ħ",HumpDownHump:"≎",HumpEqual:"≏",hybull:"⁃",hyphen:"‐",iacute:"í",Iacute:"Í",ic:"⁣",icirc:"î",Icirc:"Î",icy:"и",Icy:"И",Idot:"İ",iecy:"е",IEcy:"Е",iexcl:"¡",iff:"⇔",ifr:"𝔦",Ifr:"ℑ",igrave:"ì",Igrave:"Ì",ii:"ⅈ",iiiint:"⨌",iiint:"∭",iinfin:"⧜",iiota:"℩",ijlig:"ij",IJlig:"IJ",Im:"ℑ",imacr:"ī",Imacr:"Ī",image:"ℑ",ImaginaryI:"ⅈ",imagline:"ℐ",imagpart:"ℑ",imath:"ı",imof:"⊷",imped:"Ƶ",Implies:"⇒",in:"∈",incare:"℅",infin:"∞",infintie:"⧝",inodot:"ı",int:"∫",Int:"∬",intcal:"⊺",integers:"ℤ",Integral:"∫",intercal:"⊺",Intersection:"⋂",intlarhk:"⨗",intprod:"⨼",InvisibleComma:"⁣",InvisibleTimes:"⁢",iocy:"ё",IOcy:"Ё",iogon:"į",Iogon:"Į",iopf:"𝕚",Iopf:"𝕀",iota:"ι",Iota:"Ι",iprod:"⨼",iquest:"¿",iscr:"𝒾",Iscr:"ℐ",isin:"∈",isindot:"⋵",isinE:"⋹",isins:"⋴",isinsv:"⋳",isinv:"∈",it:"⁢",itilde:"ĩ",Itilde:"Ĩ",iukcy:"і",Iukcy:"І",iuml:"ï",Iuml:"Ï",jcirc:"ĵ",Jcirc:"Ĵ",jcy:"й",Jcy:"Й",jfr:"𝔧",Jfr:"𝔍",jmath:"ȷ",jopf:"𝕛",Jopf:"𝕁",jscr:"𝒿",Jscr:"𝒥",jsercy:"ј",Jsercy:"Ј",jukcy:"є",Jukcy:"Є",kappa:"κ",Kappa:"Κ",kappav:"ϰ",kcedil:"ķ",Kcedil:"Ķ",kcy:"к",Kcy:"К",kfr:"𝔨",Kfr:"𝔎",kgreen:"ĸ",khcy:"х",KHcy:"Х",kjcy:"ќ",KJcy:"Ќ",kopf:"𝕜",Kopf:"𝕂",kscr:"𝓀",Kscr:"𝒦",lAarr:"⇚",lacute:"ĺ",Lacute:"Ĺ",laemptyv:"⦴",lagran:"ℒ",lambda:"λ",Lambda:"Λ",lang:"⟨",Lang:"⟪",langd:"⦑",langle:"⟨",lap:"⪅",Laplacetrf:"ℒ",laquo:"«",larr:"←",lArr:"⇐",Larr:"↞",larrb:"⇤",larrbfs:"⤟",larrfs:"⤝",larrhk:"↩",larrlp:"↫",larrpl:"⤹",larrsim:"⥳",larrtl:"↢",lat:"⪫",latail:"⤙",lAtail:"⤛",late:"⪭",lates:"⪭︀",lbarr:"⤌",lBarr:"⤎",lbbrk:"❲",lbrace:"{",lbrack:"[",lbrke:"⦋",lbrksld:"⦏",lbrkslu:"⦍",lcaron:"ľ",Lcaron:"Ľ",lcedil:"ļ",Lcedil:"Ļ",lceil:"⌈",lcub:"{",lcy:"л",Lcy:"Л",ldca:"⤶",ldquo:"“",ldquor:"„",ldrdhar:"⥧",ldrushar:"⥋",ldsh:"↲",le:"≤",lE:"≦",LeftAngleBracket:"⟨",leftarrow:"←",Leftarrow:"⇐",LeftArrow:"←",LeftArrowBar:"⇤",LeftArrowRightArrow:"⇆",leftarrowtail:"↢",LeftCeiling:"⌈",LeftDoubleBracket:"⟦",LeftDownTeeVector:"⥡",LeftDownVector:"⇃",LeftDownVectorBar:"⥙",LeftFloor:"⌊",leftharpoondown:"↽",leftharpoonup:"↼",leftleftarrows:"⇇",leftrightarrow:"↔",Leftrightarrow:"⇔",LeftRightArrow:"↔",leftrightarrows:"⇆",leftrightharpoons:"⇋",leftrightsquigarrow:"↭",LeftRightVector:"⥎",LeftTee:"⊣",LeftTeeArrow:"↤",LeftTeeVector:"⥚",leftthreetimes:"⋋",LeftTriangle:"⊲",LeftTriangleBar:"⧏",LeftTriangleEqual:"⊴",LeftUpDownVector:"⥑",LeftUpTeeVector:"⥠",LeftUpVector:"↿",LeftUpVectorBar:"⥘",LeftVector:"↼",LeftVectorBar:"⥒",leg:"⋚",lEg:"⪋",leq:"≤",leqq:"≦",leqslant:"⩽",les:"⩽",lescc:"⪨",lesdot:"⩿",lesdoto:"⪁",lesdotor:"⪃",lesg:"⋚︀",lesges:"⪓",lessapprox:"⪅",lessdot:"⋖",lesseqgtr:"⋚",lesseqqgtr:"⪋",LessEqualGreater:"⋚",LessFullEqual:"≦",LessGreater:"≶",lessgtr:"≶",LessLess:"⪡",lesssim:"≲",LessSlantEqual:"⩽",LessTilde:"≲",lfisht:"⥼",lfloor:"⌊",lfr:"𝔩",Lfr:"𝔏",lg:"≶",lgE:"⪑",lHar:"⥢",lhard:"↽",lharu:"↼",lharul:"⥪",lhblk:"▄",ljcy:"љ",LJcy:"Љ",ll:"≪",Ll:"⋘",llarr:"⇇",llcorner:"⌞",Lleftarrow:"⇚",llhard:"⥫",lltri:"◺",lmidot:"ŀ",Lmidot:"Ŀ",lmoust:"⎰",lmoustache:"⎰",lnap:"⪉",lnapprox:"⪉",lne:"⪇",lnE:"≨",lneq:"⪇",lneqq:"≨",lnsim:"⋦",loang:"⟬",loarr:"⇽",lobrk:"⟦",longleftarrow:"⟵",Longleftarrow:"⟸",LongLeftArrow:"⟵",longleftrightarrow:"⟷",Longleftrightarrow:"⟺",LongLeftRightArrow:"⟷",longmapsto:"⟼",longrightarrow:"⟶",Longrightarrow:"⟹",LongRightArrow:"⟶",looparrowleft:"↫",looparrowright:"↬",lopar:"⦅",lopf:"𝕝",Lopf:"𝕃",loplus:"⨭",lotimes:"⨴",lowast:"∗",lowbar:"_",LowerLeftArrow:"↙",LowerRightArrow:"↘",loz:"◊",lozenge:"◊",lozf:"⧫",lpar:"(",lparlt:"⦓",lrarr:"⇆",lrcorner:"⌟",lrhar:"⇋",lrhard:"⥭",lrm:"‎",lrtri:"⊿",lsaquo:"‹",lscr:"𝓁",Lscr:"ℒ",lsh:"↰",Lsh:"↰",lsim:"≲",lsime:"⪍",lsimg:"⪏",lsqb:"[",lsquo:"‘",lsquor:"‚",lstrok:"ł",Lstrok:"Ł",lt:"<",Lt:"≪",LT:"<",ltcc:"⪦",ltcir:"⩹",ltdot:"⋖",lthree:"⋋",ltimes:"⋉",ltlarr:"⥶",ltquest:"⩻",ltri:"◃",ltrie:"⊴",ltrif:"◂",ltrPar:"⦖",lurdshar:"⥊",luruhar:"⥦",lvertneqq:"≨︀",lvnE:"≨︀",macr:"¯",male:"♂",malt:"✠",maltese:"✠",map:"↦",Map:"⤅",mapsto:"↦",mapstodown:"↧",mapstoleft:"↤",mapstoup:"↥",marker:"▮",mcomma:"⨩",mcy:"м",Mcy:"М",mdash:"—",mDDot:"∺",measuredangle:"∡",MediumSpace:" ",Mellintrf:"ℳ",mfr:"𝔪",Mfr:"𝔐",mho:"℧",micro:"µ",mid:"∣",midast:"*",midcir:"⫰",middot:"·",minus:"−",minusb:"⊟",minusd:"∸",minusdu:"⨪",MinusPlus:"∓",mlcp:"⫛",mldr:"…",mnplus:"∓",models:"⊧",mopf:"𝕞",Mopf:"𝕄",mp:"∓",mscr:"𝓂",Mscr:"ℳ",mstpos:"∾",mu:"μ",Mu:"Μ",multimap:"⊸",mumap:"⊸",nabla:"∇",nacute:"ń",Nacute:"Ń",nang:"∠⃒",nap:"≉",napE:"⩰̸",napid:"≋̸",napos:"ʼn",napprox:"≉",natur:"♮",natural:"♮",naturals:"ℕ",nbsp:" ",nbump:"≎̸",nbumpe:"≏̸",ncap:"⩃",ncaron:"ň",Ncaron:"Ň",ncedil:"ņ",Ncedil:"Ņ",ncong:"≇",ncongdot:"⩭̸",ncup:"⩂",ncy:"н",Ncy:"Н",ndash:"–",ne:"≠",nearhk:"⤤",nearr:"↗",neArr:"⇗",nearrow:"↗",nedot:"≐̸",NegativeMediumSpace:"​",NegativeThickSpace:"​",NegativeThinSpace:"​",NegativeVeryThinSpace:"​",nequiv:"≢",nesear:"⤨",nesim:"≂̸",NestedGreaterGreater:"≫",NestedLessLess:"≪",NewLine:"\n",nexist:"∄",nexists:"∄",nfr:"𝔫",Nfr:"𝔑",nge:"≱",ngE:"≧̸",ngeq:"≱",ngeqq:"≧̸",ngeqslant:"⩾̸",nges:"⩾̸",nGg:"⋙̸",ngsim:"≵",ngt:"≯",nGt:"≫⃒",ngtr:"≯",nGtv:"≫̸",nharr:"↮",nhArr:"⇎",nhpar:"⫲",ni:"∋",nis:"⋼",nisd:"⋺",niv:"∋",njcy:"њ",NJcy:"Њ",nlarr:"↚",nlArr:"⇍",nldr:"‥",nle:"≰",nlE:"≦̸",nleftarrow:"↚",nLeftarrow:"⇍",nleftrightarrow:"↮",nLeftrightarrow:"⇎",nleq:"≰",nleqq:"≦̸",nleqslant:"⩽̸",nles:"⩽̸",nless:"≮",nLl:"⋘̸",nlsim:"≴",nlt:"≮",nLt:"≪⃒",nltri:"⋪",nltrie:"⋬",nLtv:"≪̸",nmid:"∤",NoBreak:"⁠",NonBreakingSpace:" ",nopf:"𝕟",Nopf:"ℕ",not:"¬",Not:"⫬",NotCongruent:"≢",NotCupCap:"≭",NotDoubleVerticalBar:"∦",NotElement:"∉",NotEqual:"≠",NotEqualTilde:"≂̸",NotExists:"∄",NotGreater:"≯",NotGreaterEqual:"≱",NotGreaterFullEqual:"≧̸",NotGreaterGreater:"≫̸",NotGreaterLess:"≹",NotGreaterSlantEqual:"⩾̸",NotGreaterTilde:"≵",NotHumpDownHump:"≎̸",NotHumpEqual:"≏̸",notin:"∉",notindot:"⋵̸",notinE:"⋹̸",notinva:"∉",notinvb:"⋷",notinvc:"⋶",NotLeftTriangle:"⋪",NotLeftTriangleBar:"⧏̸",NotLeftTriangleEqual:"⋬",NotLess:"≮",NotLessEqual:"≰",NotLessGreater:"≸",NotLessLess:"≪̸",NotLessSlantEqual:"⩽̸",NotLessTilde:"≴",NotNestedGreaterGreater:"⪢̸",NotNestedLessLess:"⪡̸",notni:"∌",notniva:"∌",notnivb:"⋾",notnivc:"⋽",NotPrecedes:"⊀",NotPrecedesEqual:"⪯̸",NotPrecedesSlantEqual:"⋠",NotReverseElement:"∌",NotRightTriangle:"⋫",NotRightTriangleBar:"⧐̸",NotRightTriangleEqual:"⋭",NotSquareSubset:"⊏̸",NotSquareSubsetEqual:"⋢",NotSquareSuperset:"⊐̸",NotSquareSupersetEqual:"⋣",NotSubset:"⊂⃒",NotSubsetEqual:"⊈",NotSucceeds:"⊁",NotSucceedsEqual:"⪰̸",NotSucceedsSlantEqual:"⋡",NotSucceedsTilde:"≿̸",NotSuperset:"⊃⃒",NotSupersetEqual:"⊉",NotTilde:"≁",NotTildeEqual:"≄",NotTildeFullEqual:"≇",NotTildeTilde:"≉",NotVerticalBar:"∤",npar:"∦",nparallel:"∦",nparsl:"⫽⃥",npart:"∂̸",npolint:"⨔",npr:"⊀",nprcue:"⋠",npre:"⪯̸",nprec:"⊀",npreceq:"⪯̸",nrarr:"↛",nrArr:"⇏",nrarrc:"⤳̸",nrarrw:"↝̸",nrightarrow:"↛",nRightarrow:"⇏",nrtri:"⋫",nrtrie:"⋭",nsc:"⊁",nsccue:"⋡",nsce:"⪰̸",nscr:"𝓃",Nscr:"𝒩",nshortmid:"∤",nshortparallel:"∦",nsim:"≁",nsime:"≄",nsimeq:"≄",nsmid:"∤",nspar:"∦",nsqsube:"⋢",nsqsupe:"⋣",nsub:"⊄",nsube:"⊈",nsubE:"⫅̸",nsubset:"⊂⃒",nsubseteq:"⊈",nsubseteqq:"⫅̸",nsucc:"⊁",nsucceq:"⪰̸",nsup:"⊅",nsupe:"⊉",nsupE:"⫆̸",nsupset:"⊃⃒",nsupseteq:"⊉",nsupseteqq:"⫆̸",ntgl:"≹",ntilde:"ñ",Ntilde:"Ñ",ntlg:"≸",ntriangleleft:"⋪",ntrianglelefteq:"⋬",ntriangleright:"⋫",ntrianglerighteq:"⋭",nu:"ν",Nu:"Ν",num:"#",numero:"№",numsp:" ",nvap:"≍⃒",nvdash:"⊬",nvDash:"⊭",nVdash:"⊮",nVDash:"⊯",nvge:"≥⃒",nvgt:">⃒",nvHarr:"⤄",nvinfin:"⧞",nvlArr:"⤂",nvle:"≤⃒",nvlt:"<⃒",nvltrie:"⊴⃒",nvrArr:"⤃",nvrtrie:"⊵⃒",nvsim:"∼⃒",nwarhk:"⤣",nwarr:"↖",nwArr:"⇖",nwarrow:"↖",nwnear:"⤧",oacute:"ó",Oacute:"Ó",oast:"⊛",ocir:"⊚",ocirc:"ô",Ocirc:"Ô",ocy:"о",Ocy:"О",odash:"⊝",odblac:"ő",Odblac:"Ő",odiv:"⨸",odot:"⊙",odsold:"⦼",oelig:"œ",OElig:"Œ",ofcir:"⦿",ofr:"𝔬",Ofr:"𝔒",ogon:"˛",ograve:"ò",Ograve:"Ò",ogt:"⧁",ohbar:"⦵",ohm:"Ω",oint:"∮",olarr:"↺",olcir:"⦾",olcross:"⦻",oline:"‾",olt:"⧀",omacr:"ō",Omacr:"Ō",omega:"ω",Omega:"Ω",omicron:"ο",Omicron:"Ο",omid:"⦶",ominus:"⊖",oopf:"𝕠",Oopf:"𝕆",opar:"⦷",OpenCurlyDoubleQuote:"“",OpenCurlyQuote:"‘",operp:"⦹",oplus:"⊕",or:"∨",Or:"⩔",orarr:"↻",ord:"⩝",order:"ℴ",orderof:"ℴ",ordf:"ª",ordm:"º",origof:"⊶",oror:"⩖",orslope:"⩗",orv:"⩛",oS:"Ⓢ",oscr:"ℴ",Oscr:"𝒪",oslash:"ø",Oslash:"Ø",osol:"⊘",otilde:"õ",Otilde:"Õ",otimes:"⊗",Otimes:"⨷",otimesas:"⨶",ouml:"ö",Ouml:"Ö",ovbar:"⌽",OverBar:"‾",OverBrace:"⏞",OverBracket:"⎴",OverParenthesis:"⏜",par:"∥",para:"¶",parallel:"∥",parsim:"⫳",parsl:"⫽",part:"∂",PartialD:"∂",pcy:"п",Pcy:"П",percnt:"%",period:".",permil:"‰",perp:"⊥",pertenk:"‱",pfr:"𝔭",Pfr:"𝔓",phi:"φ",Phi:"Φ",phiv:"ϕ",phmmat:"ℳ",phone:"☎",pi:"π",Pi:"Π",pitchfork:"⋔",piv:"ϖ",planck:"ℏ",planckh:"ℎ",plankv:"ℏ",plus:"+",plusacir:"⨣",plusb:"⊞",pluscir:"⨢",plusdo:"∔",plusdu:"⨥",pluse:"⩲",PlusMinus:"±",plusmn:"±",plussim:"⨦",plustwo:"⨧",pm:"±",Poincareplane:"ℌ",pointint:"⨕",popf:"𝕡",Popf:"ℙ",pound:"£",pr:"≺",Pr:"⪻",prap:"⪷",prcue:"≼",pre:"⪯",prE:"⪳",prec:"≺",precapprox:"⪷",preccurlyeq:"≼",Precedes:"≺",PrecedesEqual:"⪯",PrecedesSlantEqual:"≼",PrecedesTilde:"≾",preceq:"⪯",precnapprox:"⪹",precneqq:"⪵",precnsim:"⋨",precsim:"≾",prime:"′",Prime:"″",primes:"ℙ",prnap:"⪹",prnE:"⪵",prnsim:"⋨",prod:"∏",Product:"∏",profalar:"⌮",profline:"⌒",profsurf:"⌓",prop:"∝",Proportion:"∷",Proportional:"∝",propto:"∝",prsim:"≾",prurel:"⊰",pscr:"𝓅",Pscr:"𝒫",psi:"ψ",Psi:"Ψ",puncsp:" ",qfr:"𝔮",Qfr:"𝔔",qint:"⨌",qopf:"𝕢",Qopf:"ℚ",qprime:"⁗",qscr:"𝓆",Qscr:"𝒬",quaternions:"ℍ",quatint:"⨖",quest:"?",questeq:"≟",quot:'"',QUOT:'"',rAarr:"⇛",race:"∽̱",racute:"ŕ",Racute:"Ŕ",radic:"√",raemptyv:"⦳",rang:"⟩",Rang:"⟫",rangd:"⦒",range:"⦥",rangle:"⟩",raquo:"»",rarr:"→",rArr:"⇒",Rarr:"↠",rarrap:"⥵",rarrb:"⇥",rarrbfs:"⤠",rarrc:"⤳",rarrfs:"⤞",rarrhk:"↪",rarrlp:"↬",rarrpl:"⥅",rarrsim:"⥴",rarrtl:"↣",Rarrtl:"⤖",rarrw:"↝",ratail:"⤚",rAtail:"⤜",ratio:"∶",rationals:"ℚ",rbarr:"⤍",rBarr:"⤏",RBarr:"⤐",rbbrk:"❳",rbrace:"}",rbrack:"]",rbrke:"⦌",rbrksld:"⦎",rbrkslu:"⦐",rcaron:"ř",Rcaron:"Ř",rcedil:"ŗ",Rcedil:"Ŗ",rceil:"⌉",rcub:"}",rcy:"р",Rcy:"Р",rdca:"⤷",rdldhar:"⥩",rdquo:"”",rdquor:"”",rdsh:"↳",Re:"ℜ",real:"ℜ",realine:"ℛ",realpart:"ℜ",reals:"ℝ",rect:"▭",reg:"®",REG:"®",ReverseElement:"∋",ReverseEquilibrium:"⇋",ReverseUpEquilibrium:"⥯",rfisht:"⥽",rfloor:"⌋",rfr:"𝔯",Rfr:"ℜ",rHar:"⥤",rhard:"⇁",rharu:"⇀",rharul:"⥬",rho:"ρ",Rho:"Ρ",rhov:"ϱ",RightAngleBracket:"⟩",rightarrow:"→",Rightarrow:"⇒",RightArrow:"→",RightArrowBar:"⇥",RightArrowLeftArrow:"⇄",rightarrowtail:"↣",RightCeiling:"⌉",RightDoubleBracket:"⟧",RightDownTeeVector:"⥝",RightDownVector:"⇂",RightDownVectorBar:"⥕",RightFloor:"⌋",rightharpoondown:"⇁",rightharpoonup:"⇀",rightleftarrows:"⇄",rightleftharpoons:"⇌",rightrightarrows:"⇉",rightsquigarrow:"↝",RightTee:"⊢",RightTeeArrow:"↦",RightTeeVector:"⥛",rightthreetimes:"⋌",RightTriangle:"⊳",RightTriangleBar:"⧐",RightTriangleEqual:"⊵",RightUpDownVector:"⥏",RightUpTeeVector:"⥜",RightUpVector:"↾",RightUpVectorBar:"⥔",RightVector:"⇀",RightVectorBar:"⥓",ring:"˚",risingdotseq:"≓",rlarr:"⇄",rlhar:"⇌",rlm:"‏",rmoust:"⎱",rmoustache:"⎱",rnmid:"⫮",roang:"⟭",roarr:"⇾",robrk:"⟧",ropar:"⦆",ropf:"𝕣",Ropf:"ℝ",roplus:"⨮",rotimes:"⨵",RoundImplies:"⥰",rpar:")",rpargt:"⦔",rppolint:"⨒",rrarr:"⇉",Rrightarrow:"⇛",rsaquo:"›",rscr:"𝓇",Rscr:"ℛ",rsh:"↱",Rsh:"↱",rsqb:"]",rsquo:"’",rsquor:"’",rthree:"⋌",rtimes:"⋊",rtri:"▹",rtrie:"⊵",rtrif:"▸",rtriltri:"⧎",RuleDelayed:"⧴",ruluhar:"⥨",rx:"℞",sacute:"ś",Sacute:"Ś",sbquo:"‚",sc:"≻",Sc:"⪼",scap:"⪸",scaron:"š",Scaron:"Š",sccue:"≽",sce:"⪰",scE:"⪴",scedil:"ş",Scedil:"Ş",scirc:"ŝ",Scirc:"Ŝ",scnap:"⪺",scnE:"⪶",scnsim:"⋩",scpolint:"⨓",scsim:"≿",scy:"с",Scy:"С",sdot:"⋅",sdotb:"⊡",sdote:"⩦",searhk:"⤥",searr:"↘",seArr:"⇘",searrow:"↘",sect:"§",semi:";",seswar:"⤩",setminus:"∖",setmn:"∖",sext:"✶",sfr:"𝔰",Sfr:"𝔖",sfrown:"⌢",sharp:"♯",shchcy:"щ",SHCHcy:"Щ",shcy:"ш",SHcy:"Ш",ShortDownArrow:"↓",ShortLeftArrow:"←",shortmid:"∣",shortparallel:"∥",ShortRightArrow:"→",ShortUpArrow:"↑",shy:"­",sigma:"σ",Sigma:"Σ",sigmaf:"ς",sigmav:"ς",sim:"∼",simdot:"⩪",sime:"≃",simeq:"≃",simg:"⪞",simgE:"⪠",siml:"⪝",simlE:"⪟",simne:"≆",simplus:"⨤",simrarr:"⥲",slarr:"←",SmallCircle:"∘",smallsetminus:"∖",smashp:"⨳",smeparsl:"⧤",smid:"∣",smile:"⌣",smt:"⪪",smte:"⪬",smtes:"⪬︀",softcy:"ь",SOFTcy:"Ь",sol:"/",solb:"⧄",solbar:"⌿",sopf:"𝕤",Sopf:"𝕊",spades:"♠",spadesuit:"♠",spar:"∥",sqcap:"⊓",sqcaps:"⊓︀",sqcup:"⊔",sqcups:"⊔︀",Sqrt:"√",sqsub:"⊏",sqsube:"⊑",sqsubset:"⊏",sqsubseteq:"⊑",sqsup:"⊐",sqsupe:"⊒",sqsupset:"⊐",sqsupseteq:"⊒",squ:"□",square:"□",Square:"□",SquareIntersection:"⊓",SquareSubset:"⊏",SquareSubsetEqual:"⊑",SquareSuperset:"⊐",SquareSupersetEqual:"⊒",SquareUnion:"⊔",squarf:"▪",squf:"▪",srarr:"→",sscr:"𝓈",Sscr:"𝒮",ssetmn:"∖",ssmile:"⌣",sstarf:"⋆",star:"☆",Star:"⋆",starf:"★",straightepsilon:"ϵ",straightphi:"ϕ",strns:"¯",sub:"⊂",Sub:"⋐",subdot:"⪽",sube:"⊆",subE:"⫅",subedot:"⫃",submult:"⫁",subne:"⊊",subnE:"⫋",subplus:"⪿",subrarr:"⥹",subset:"⊂",Subset:"⋐",subseteq:"⊆",subseteqq:"⫅",SubsetEqual:"⊆",subsetneq:"⊊",subsetneqq:"⫋",subsim:"⫇",subsub:"⫕",subsup:"⫓",succ:"≻",succapprox:"⪸",succcurlyeq:"≽",Succeeds:"≻",SucceedsEqual:"⪰",SucceedsSlantEqual:"≽",SucceedsTilde:"≿",succeq:"⪰",succnapprox:"⪺",succneqq:"⪶",succnsim:"⋩",succsim:"≿",SuchThat:"∋",sum:"∑",Sum:"∑",sung:"♪",sup:"⊃",Sup:"⋑",sup1:"¹",sup2:"²",sup3:"³",supdot:"⪾",supdsub:"⫘",supe:"⊇",supE:"⫆",supedot:"⫄",Superset:"⊃",SupersetEqual:"⊇",suphsol:"⟉",suphsub:"⫗",suplarr:"⥻",supmult:"⫂",supne:"⊋",supnE:"⫌",supplus:"⫀",supset:"⊃",Supset:"⋑",supseteq:"⊇",supseteqq:"⫆",supsetneq:"⊋",supsetneqq:"⫌",supsim:"⫈",supsub:"⫔",supsup:"⫖",swarhk:"⤦",swarr:"↙",swArr:"⇙",swarrow:"↙",swnwar:"⤪",szlig:"ß",Tab:"\t",target:"⌖",tau:"τ",Tau:"Τ",tbrk:"⎴",tcaron:"ť",Tcaron:"Ť",tcedil:"ţ",Tcedil:"Ţ",tcy:"т",Tcy:"Т",tdot:"⃛",telrec:"⌕",tfr:"𝔱",Tfr:"𝔗",there4:"∴",therefore:"∴",Therefore:"∴",theta:"θ",Theta:"Θ",thetasym:"ϑ",thetav:"ϑ",thickapprox:"≈",thicksim:"∼",ThickSpace:"  ",thinsp:" ",ThinSpace:" ",thkap:"≈",thksim:"∼",thorn:"þ",THORN:"Þ",tilde:"˜",Tilde:"∼",TildeEqual:"≃",TildeFullEqual:"≅",TildeTilde:"≈",times:"×",timesb:"⊠",timesbar:"⨱",timesd:"⨰",tint:"∭",toea:"⤨",top:"⊤",topbot:"⌶",topcir:"⫱",topf:"𝕥",Topf:"𝕋",topfork:"⫚",tosa:"⤩",tprime:"‴",trade:"™",TRADE:"™",triangle:"▵",triangledown:"▿",triangleleft:"◃",trianglelefteq:"⊴",triangleq:"≜",triangleright:"▹",trianglerighteq:"⊵",tridot:"◬",trie:"≜",triminus:"⨺",TripleDot:"⃛",triplus:"⨹",trisb:"⧍",tritime:"⨻",trpezium:"⏢",tscr:"𝓉",Tscr:"𝒯",tscy:"ц",TScy:"Ц",tshcy:"ћ",TSHcy:"Ћ",tstrok:"ŧ",Tstrok:"Ŧ",twixt:"≬",twoheadleftarrow:"↞",twoheadrightarrow:"↠",uacute:"ú",Uacute:"Ú",uarr:"↑",uArr:"⇑",Uarr:"↟",Uarrocir:"⥉",ubrcy:"ў",Ubrcy:"Ў",ubreve:"ŭ",Ubreve:"Ŭ",ucirc:"û",Ucirc:"Û",ucy:"у",Ucy:"У",udarr:"⇅",udblac:"ű",Udblac:"Ű",udhar:"⥮",ufisht:"⥾",ufr:"𝔲",Ufr:"𝔘",ugrave:"ù",Ugrave:"Ù",uHar:"⥣",uharl:"↿",uharr:"↾",uhblk:"▀",ulcorn:"⌜",ulcorner:"⌜",ulcrop:"⌏",ultri:"◸",umacr:"ū",Umacr:"Ū",uml:"¨",UnderBar:"_",UnderBrace:"⏟",UnderBracket:"⎵",UnderParenthesis:"⏝",Union:"⋃",UnionPlus:"⊎",uogon:"ų",Uogon:"Ų",uopf:"𝕦",Uopf:"𝕌",uparrow:"↑",Uparrow:"⇑",UpArrow:"↑",UpArrowBar:"⤒",UpArrowDownArrow:"⇅",updownarrow:"↕",Updownarrow:"⇕",UpDownArrow:"↕",UpEquilibrium:"⥮",upharpoonleft:"↿",upharpoonright:"↾",uplus:"⊎",UpperLeftArrow:"↖",UpperRightArrow:"↗",upsi:"υ",Upsi:"ϒ",upsih:"ϒ",upsilon:"υ",Upsilon:"Υ",UpTee:"⊥",UpTeeArrow:"↥",upuparrows:"⇈",urcorn:"⌝",urcorner:"⌝",urcrop:"⌎",uring:"ů",Uring:"Ů",urtri:"◹",uscr:"𝓊",Uscr:"𝒰",utdot:"⋰",utilde:"ũ",Utilde:"Ũ",utri:"▵",utrif:"▴",uuarr:"⇈",uuml:"ü",Uuml:"Ü",uwangle:"⦧",vangrt:"⦜",varepsilon:"ϵ",varkappa:"ϰ",varnothing:"∅",varphi:"ϕ",varpi:"ϖ",varpropto:"∝",varr:"↕",vArr:"⇕",varrho:"ϱ",varsigma:"ς",varsubsetneq:"⊊︀",varsubsetneqq:"⫋︀",varsupsetneq:"⊋︀",varsupsetneqq:"⫌︀",vartheta:"ϑ",vartriangleleft:"⊲",vartriangleright:"⊳",vBar:"⫨",Vbar:"⫫",vBarv:"⫩",vcy:"в",Vcy:"В",vdash:"⊢",vDash:"⊨",Vdash:"⊩",VDash:"⊫",Vdashl:"⫦",vee:"∨",Vee:"⋁",veebar:"⊻",veeeq:"≚",vellip:"⋮",verbar:"|",Verbar:"‖",vert:"|",Vert:"‖",VerticalBar:"∣",VerticalLine:"|",VerticalSeparator:"❘",VerticalTilde:"≀",VeryThinSpace:" ",vfr:"𝔳",Vfr:"𝔙",vltri:"⊲",vnsub:"⊂⃒",vnsup:"⊃⃒",vopf:"𝕧",Vopf:"𝕍",vprop:"∝",vrtri:"⊳",vscr:"𝓋",Vscr:"𝒱",vsubne:"⊊︀",vsubnE:"⫋︀",vsupne:"⊋︀",vsupnE:"⫌︀",Vvdash:"⊪",vzigzag:"⦚",wcirc:"ŵ",Wcirc:"Ŵ",wedbar:"⩟",wedge:"∧",Wedge:"⋀",wedgeq:"≙",weierp:"℘",wfr:"𝔴",Wfr:"𝔚",wopf:"𝕨",Wopf:"𝕎",wp:"℘",wr:"≀",wreath:"≀",wscr:"𝓌",Wscr:"𝒲",xcap:"⋂",xcirc:"◯",xcup:"⋃",xdtri:"▽",xfr:"𝔵",Xfr:"𝔛",xharr:"⟷",xhArr:"⟺",xi:"ξ",Xi:"Ξ",xlarr:"⟵",xlArr:"⟸",xmap:"⟼",xnis:"⋻",xodot:"⨀",xopf:"𝕩",Xopf:"𝕏",xoplus:"⨁",xotime:"⨂",xrarr:"⟶",xrArr:"⟹",xscr:"𝓍",Xscr:"𝒳",xsqcup:"⨆",xuplus:"⨄",xutri:"△",xvee:"⋁",xwedge:"⋀",yacute:"ý",Yacute:"Ý",yacy:"я",YAcy:"Я",ycirc:"ŷ",Ycirc:"Ŷ",ycy:"ы",Ycy:"Ы",yen:"¥",yfr:"𝔶",Yfr:"𝔜",yicy:"ї",YIcy:"Ї",yopf:"𝕪",Yopf:"𝕐",yscr:"𝓎",Yscr:"𝒴",yucy:"ю",YUcy:"Ю",yuml:"ÿ",Yuml:"Ÿ",zacute:"ź",Zacute:"Ź",zcaron:"ž",Zcaron:"Ž",zcy:"з",Zcy:"З",zdot:"ż",Zdot:"Ż",zeetrf:"ℨ",ZeroWidthSpace:"​",zeta:"ζ",Zeta:"Ζ",zfr:"𝔷",Zfr:"ℨ",zhcy:"ж",ZHcy:"Ж",zigrarr:"⇝",zopf:"𝕫",Zopf:"ℤ",zscr:"𝓏",Zscr:"𝒵",zwj:"‍",zwnj:"‌"},h={aacute:"á",Aacute:"Á",acirc:"â",Acirc:"Â",acute:"´",aelig:"æ",AElig:"Æ",agrave:"à",Agrave:"À",amp:"&",AMP:"&",aring:"å",Aring:"Å",atilde:"ã",Atilde:"Ã",auml:"ä",Auml:"Ä",brvbar:"¦",ccedil:"ç",Ccedil:"Ç",cedil:"¸",cent:"¢",copy:"©",COPY:"©",curren:"¤",deg:"°",divide:"÷",eacute:"é",Eacute:"É",ecirc:"ê",Ecirc:"Ê",egrave:"è",Egrave:"È",eth:"ð",ETH:"Ð",euml:"ë",Euml:"Ë",frac12:"½",frac14:"¼",frac34:"¾",gt:">",GT:">",iacute:"í",Iacute:"Í",icirc:"î",Icirc:"Î",iexcl:"¡",igrave:"ì",Igrave:"Ì",iquest:"¿",iuml:"ï",Iuml:"Ï",laquo:"«",lt:"<",LT:"<",macr:"¯",micro:"µ",middot:"·",nbsp:" ",not:"¬",ntilde:"ñ",Ntilde:"Ñ",oacute:"ó",Oacute:"Ó",ocirc:"ô",Ocirc:"Ô",ograve:"ò",Ograve:"Ò",ordf:"ª",ordm:"º",oslash:"ø",Oslash:"Ø",otilde:"õ",Otilde:"Õ",ouml:"ö",Ouml:"Ö",para:"¶",plusmn:"±",pound:"£",quot:'"',QUOT:'"',raquo:"»",reg:"®",REG:"®",sect:"§",shy:"­",sup1:"¹",sup2:"²",sup3:"³",szlig:"ß",thorn:"þ",THORN:"Þ",times:"×",uacute:"ú",Uacute:"Ú",ucirc:"û",Ucirc:"Û",ugrave:"ù",Ugrave:"Ù",uml:"¨",uuml:"ü",Uuml:"Ü",yacute:"ý",Yacute:"Ý",yen:"¥",yuml:"ÿ"},g={0:"�",128:"€",130:"‚",131:"ƒ",132:"„",133:"…",134:"†",135:"‡",136:"ˆ",137:"‰",138:"Š",139:"‹",140:"Œ",142:"Ž",145:"‘",146:"’",147:"“",148:"”",149:"•",150:"–",151:"—",152:"˜",153:"™",154:"š",155:"›",156:"œ",158:"ž",159:"Ÿ"},E=[1,2,3,4,5,6,7,8,11,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,64976,64977,64978,64979,64980,64981,64982,64983,64984,64985,64986,64987,64988,64989,64990,64991,64992,64993,64994,64995,64996,64997,64998,64999,65e3,65001,65002,65003,65004,65005,65006,65007,65534,65535,131070,131071,196606,196607,262142,262143,327678,327679,393214,393215,458750,458751,524286,524287,589822,589823,655358,655359,720894,720895,786430,786431,851966,851967,917502,917503,983038,983039,1048574,1048575,1114110,1114111],_=String.fromCharCode,v={}.hasOwnProperty,T=function(C,L){return v.call(C,L)},H=function(C,L){if(!C)return L;var $,k={};for($ in L)k[$]=T(C,$)?C[$]:L[$];return k},I=function(C,L){var k="";return C>=55296&&C<=57343||C>1114111?(L&&K("character reference outside the permissible Unicode range"),"�"):T(g,C)?(L&&K("disallowed character reference"),g[C]):(L&&function(C,L){for(var k=-1,$=C.length;++k<$;)if(C[k]==L)return!0;return!1}(E,C)&&K("disallowed character reference"),C>65535&&(k+=_((C-=65536)>>>10&1023|55296),C=56320|1023&C),k+=_(C))},W=function(C){return"&#x"+C.toString(16).toUpperCase()+";"},le=function(C){return"&#"+C+";"},K=function(C){throw Error("Parse error: "+C)},O=function(C,L){(L=H(L,O.options)).strict&&b.test(C)&&K("forbidden code point");var $=L.encodeEverything,j=L.useNamedReferences,ge=L.allowUnsafeSymbols,pe=L.decimal?le:W,ue=function(ce){return pe(ce.charCodeAt(0))};return $?(C=C.replace(i,(function(ce){return j&&T(c,ce)?"&"+c[ce]+";":ue(ce)})),j&&(C=C.replace(/>\u20D2/g,">⃒").replace(/<\u20D2/g,"<⃒").replace(/fj/g,"fj")),j&&(C=C.replace(u,(function(ce){return"&"+c[ce]+";"})))):j?(ge||(C=C.replace(p,(function(ce){return"&"+c[ce]+";"}))),C=(C=C.replace(/>\u20D2/g,">⃒").replace(/<\u20D2/g,"<⃒")).replace(u,(function(ce){return"&"+c[ce]+";"}))):ge||(C=C.replace(p,ue)),C.replace(s,(function(ce){var bt=ce.charCodeAt(0),Ut=ce.charCodeAt(1);return pe(1024*(bt-55296)+Ut-56320+65536)})).replace(l,ue)};O.options={allowUnsafeSymbols:!1,encodeEverything:!1,strict:!1,useNamedReferences:!1,decimal:!1};var V=function(C,L){var k=(L=H(L,V.options)).strict;return k&&f.test(C)&&K("malformed character reference"),C.replace(A,(function($,j,ge,pe,ue,ce,bt,Ut,At){var je,xt,ne,Oe,Be,Ne;return j?y[Be=j]:ge?(Be=ge,(Ne=pe)&&L.isAttributeValue?(k&&"="==Ne&&K("`&` did not start a character reference"),$):(k&&K("named character reference was not terminated by a semicolon"),h[Be]+(Ne||""))):ue?(ne=ue,xt=ce,k&&!xt&&K("character reference was not terminated by a semicolon"),je=parseInt(ne,10),I(je,k)):bt?(Oe=bt,xt=Ut,k&&!xt&&K("character reference was not terminated by a semicolon"),je=parseInt(Oe,16),I(je,k)):(k&&K("named character reference was not terminated by a semicolon"),$)}))};V.options={isAttributeValue:!1,strict:!1};var x={version:"1.2.0",encode:O,decode:V,escape:function(C){return C.replace(p,(function(L){return d[L]}))},unescape:V};if(r&&!r.nodeType)if(o)o.exports=x;else for(var S in x)T(x,S)&&(r[S]=x[S]);else n.he=x}(xe)}(Ss,Ss.exports);var R_=Ss.exports,ie={},Jf={Aacute:"Á",aacute:"á",Abreve:"Ă",abreve:"ă",ac:"∾",acd:"∿",acE:"∾̳",Acirc:"Â",acirc:"â",acute:"´",Acy:"А",acy:"а",AElig:"Æ",aelig:"æ",af:"⁡",Afr:"𝔄",afr:"𝔞",Agrave:"À",agrave:"à",alefsym:"ℵ",aleph:"ℵ",Alpha:"Α",alpha:"α",Amacr:"Ā",amacr:"ā",amalg:"⨿",amp:"&",AMP:"&",andand:"⩕",And:"⩓",and:"∧",andd:"⩜",andslope:"⩘",andv:"⩚",ang:"∠",ange:"⦤",angle:"∠",angmsdaa:"⦨",angmsdab:"⦩",angmsdac:"⦪",angmsdad:"⦫",angmsdae:"⦬",angmsdaf:"⦭",angmsdag:"⦮",angmsdah:"⦯",angmsd:"∡",angrt:"∟",angrtvb:"⊾",angrtvbd:"⦝",angsph:"∢",angst:"Å",angzarr:"⍼",Aogon:"Ą",aogon:"ą",Aopf:"𝔸",aopf:"𝕒",apacir:"⩯",ap:"≈",apE:"⩰",ape:"≊",apid:"≋",apos:"'",ApplyFunction:"⁡",approx:"≈",approxeq:"≊",Aring:"Å",aring:"å",Ascr:"𝒜",ascr:"𝒶",Assign:"≔",ast:"*",asymp:"≈",asympeq:"≍",Atilde:"Ã",atilde:"ã",Auml:"Ä",auml:"ä",awconint:"∳",awint:"⨑",backcong:"≌",backepsilon:"϶",backprime:"‵",backsim:"∽",backsimeq:"⋍",Backslash:"∖",Barv:"⫧",barvee:"⊽",barwed:"⌅",Barwed:"⌆",barwedge:"⌅",bbrk:"⎵",bbrktbrk:"⎶",bcong:"≌",Bcy:"Б",bcy:"б",bdquo:"„",becaus:"∵",because:"∵",Because:"∵",bemptyv:"⦰",bepsi:"϶",bernou:"ℬ",Bernoullis:"ℬ",Beta:"Β",beta:"β",beth:"ℶ",between:"≬",Bfr:"𝔅",bfr:"𝔟",bigcap:"⋂",bigcirc:"◯",bigcup:"⋃",bigodot:"⨀",bigoplus:"⨁",bigotimes:"⨂",bigsqcup:"⨆",bigstar:"★",bigtriangledown:"▽",bigtriangleup:"△",biguplus:"⨄",bigvee:"⋁",bigwedge:"⋀",bkarow:"⤍",blacklozenge:"⧫",blacksquare:"▪",blacktriangle:"▴",blacktriangledown:"▾",blacktriangleleft:"◂",blacktriangleright:"▸",blank:"␣",blk12:"▒",blk14:"░",blk34:"▓",block:"█",bne:"=⃥",bnequiv:"≡⃥",bNot:"⫭",bnot:"⌐",Bopf:"𝔹",bopf:"𝕓",bot:"⊥",bottom:"⊥",bowtie:"⋈",boxbox:"⧉",boxdl:"┐",boxdL:"╕",boxDl:"╖",boxDL:"╗",boxdr:"┌",boxdR:"╒",boxDr:"╓",boxDR:"╔",boxh:"─",boxH:"═",boxhd:"┬",boxHd:"╤",boxhD:"╥",boxHD:"╦",boxhu:"┴",boxHu:"╧",boxhU:"╨",boxHU:"╩",boxminus:"⊟",boxplus:"⊞",boxtimes:"⊠",boxul:"┘",boxuL:"╛",boxUl:"╜",boxUL:"╝",boxur:"└",boxuR:"╘",boxUr:"╙",boxUR:"╚",boxv:"│",boxV:"║",boxvh:"┼",boxvH:"╪",boxVh:"╫",boxVH:"╬",boxvl:"┤",boxvL:"╡",boxVl:"╢",boxVL:"╣",boxvr:"├",boxvR:"╞",boxVr:"╟",boxVR:"╠",bprime:"‵",breve:"˘",Breve:"˘",brvbar:"¦",bscr:"𝒷",Bscr:"ℬ",bsemi:"⁏",bsim:"∽",bsime:"⋍",bsolb:"⧅",bsol:"\\",bsolhsub:"⟈",bull:"•",bullet:"•",bump:"≎",bumpE:"⪮",bumpe:"≏",Bumpeq:"≎",bumpeq:"≏",Cacute:"Ć",cacute:"ć",capand:"⩄",capbrcup:"⩉",capcap:"⩋",cap:"∩",Cap:"⋒",capcup:"⩇",capdot:"⩀",CapitalDifferentialD:"ⅅ",caps:"∩︀",caret:"⁁",caron:"ˇ",Cayleys:"ℭ",ccaps:"⩍",Ccaron:"Č",ccaron:"č",Ccedil:"Ç",ccedil:"ç",Ccirc:"Ĉ",ccirc:"ĉ",Cconint:"∰",ccups:"⩌",ccupssm:"⩐",Cdot:"Ċ",cdot:"ċ",cedil:"¸",Cedilla:"¸",cemptyv:"⦲",cent:"¢",centerdot:"·",CenterDot:"·",cfr:"𝔠",Cfr:"ℭ",CHcy:"Ч",chcy:"ч",check:"✓",checkmark:"✓",Chi:"Χ",chi:"χ",circ:"ˆ",circeq:"≗",circlearrowleft:"↺",circlearrowright:"↻",circledast:"⊛",circledcirc:"⊚",circleddash:"⊝",CircleDot:"⊙",circledR:"®",circledS:"Ⓢ",CircleMinus:"⊖",CirclePlus:"⊕",CircleTimes:"⊗",cir:"○",cirE:"⧃",cire:"≗",cirfnint:"⨐",cirmid:"⫯",cirscir:"⧂",ClockwiseContourIntegral:"∲",CloseCurlyDoubleQuote:"”",CloseCurlyQuote:"’",clubs:"♣",clubsuit:"♣",colon:":",Colon:"∷",Colone:"⩴",colone:"≔",coloneq:"≔",comma:",",commat:"@",comp:"∁",compfn:"∘",complement:"∁",complexes:"ℂ",cong:"≅",congdot:"⩭",Congruent:"≡",conint:"∮",Conint:"∯",ContourIntegral:"∮",copf:"𝕔",Copf:"ℂ",coprod:"∐",Coproduct:"∐",copy:"©",COPY:"©",copysr:"℗",CounterClockwiseContourIntegral:"∳",crarr:"↵",cross:"✗",Cross:"⨯",Cscr:"𝒞",cscr:"𝒸",csub:"⫏",csube:"⫑",csup:"⫐",csupe:"⫒",ctdot:"⋯",cudarrl:"⤸",cudarrr:"⤵",cuepr:"⋞",cuesc:"⋟",cularr:"↶",cularrp:"⤽",cupbrcap:"⩈",cupcap:"⩆",CupCap:"≍",cup:"∪",Cup:"⋓",cupcup:"⩊",cupdot:"⊍",cupor:"⩅",cups:"∪︀",curarr:"↷",curarrm:"⤼",curlyeqprec:"⋞",curlyeqsucc:"⋟",curlyvee:"⋎",curlywedge:"⋏",curren:"¤",curvearrowleft:"↶",curvearrowright:"↷",cuvee:"⋎",cuwed:"⋏",cwconint:"∲",cwint:"∱",cylcty:"⌭",dagger:"†",Dagger:"‡",daleth:"ℸ",darr:"↓",Darr:"↡",dArr:"⇓",dash:"‐",Dashv:"⫤",dashv:"⊣",dbkarow:"⤏",dblac:"˝",Dcaron:"Ď",dcaron:"ď",Dcy:"Д",dcy:"д",ddagger:"‡",ddarr:"⇊",DD:"ⅅ",dd:"ⅆ",DDotrahd:"⤑",ddotseq:"⩷",deg:"°",Del:"∇",Delta:"Δ",delta:"δ",demptyv:"⦱",dfisht:"⥿",Dfr:"𝔇",dfr:"𝔡",dHar:"⥥",dharl:"⇃",dharr:"⇂",DiacriticalAcute:"´",DiacriticalDot:"˙",DiacriticalDoubleAcute:"˝",DiacriticalGrave:"`",DiacriticalTilde:"˜",diam:"⋄",diamond:"⋄",Diamond:"⋄",diamondsuit:"♦",diams:"♦",die:"¨",DifferentialD:"ⅆ",digamma:"ϝ",disin:"⋲",div:"÷",divide:"÷",divideontimes:"⋇",divonx:"⋇",DJcy:"Ђ",djcy:"ђ",dlcorn:"⌞",dlcrop:"⌍",dollar:"$",Dopf:"𝔻",dopf:"𝕕",Dot:"¨",dot:"˙",DotDot:"⃜",doteq:"≐",doteqdot:"≑",DotEqual:"≐",dotminus:"∸",dotplus:"∔",dotsquare:"⊡",doublebarwedge:"⌆",DoubleContourIntegral:"∯",DoubleDot:"¨",DoubleDownArrow:"⇓",DoubleLeftArrow:"⇐",DoubleLeftRightArrow:"⇔",DoubleLeftTee:"⫤",DoubleLongLeftArrow:"⟸",DoubleLongLeftRightArrow:"⟺",DoubleLongRightArrow:"⟹",DoubleRightArrow:"⇒",DoubleRightTee:"⊨",DoubleUpArrow:"⇑",DoubleUpDownArrow:"⇕",DoubleVerticalBar:"∥",DownArrowBar:"⤓",downarrow:"↓",DownArrow:"↓",Downarrow:"⇓",DownArrowUpArrow:"⇵",DownBreve:"̑",downdownarrows:"⇊",downharpoonleft:"⇃",downharpoonright:"⇂",DownLeftRightVector:"⥐",DownLeftTeeVector:"⥞",DownLeftVectorBar:"⥖",DownLeftVector:"↽",DownRightTeeVector:"⥟",DownRightVectorBar:"⥗",DownRightVector:"⇁",DownTeeArrow:"↧",DownTee:"⊤",drbkarow:"⤐",drcorn:"⌟",drcrop:"⌌",Dscr:"𝒟",dscr:"𝒹",DScy:"Ѕ",dscy:"ѕ",dsol:"⧶",Dstrok:"Đ",dstrok:"đ",dtdot:"⋱",dtri:"▿",dtrif:"▾",duarr:"⇵",duhar:"⥯",dwangle:"⦦",DZcy:"Џ",dzcy:"џ",dzigrarr:"⟿",Eacute:"É",eacute:"é",easter:"⩮",Ecaron:"Ě",ecaron:"ě",Ecirc:"Ê",ecirc:"ê",ecir:"≖",ecolon:"≕",Ecy:"Э",ecy:"э",eDDot:"⩷",Edot:"Ė",edot:"ė",eDot:"≑",ee:"ⅇ",efDot:"≒",Efr:"𝔈",efr:"𝔢",eg:"⪚",Egrave:"È",egrave:"è",egs:"⪖",egsdot:"⪘",el:"⪙",Element:"∈",elinters:"⏧",ell:"ℓ",els:"⪕",elsdot:"⪗",Emacr:"Ē",emacr:"ē",empty:"∅",emptyset:"∅",EmptySmallSquare:"◻",emptyv:"∅",EmptyVerySmallSquare:"▫",emsp13:" ",emsp14:" ",emsp:" ",ENG:"Ŋ",eng:"ŋ",ensp:" ",Eogon:"Ę",eogon:"ę",Eopf:"𝔼",eopf:"𝕖",epar:"⋕",eparsl:"⧣",eplus:"⩱",epsi:"ε",Epsilon:"Ε",epsilon:"ε",epsiv:"ϵ",eqcirc:"≖",eqcolon:"≕",eqsim:"≂",eqslantgtr:"⪖",eqslantless:"⪕",Equal:"⩵",equals:"=",EqualTilde:"≂",equest:"≟",Equilibrium:"⇌",equiv:"≡",equivDD:"⩸",eqvparsl:"⧥",erarr:"⥱",erDot:"≓",escr:"ℯ",Escr:"ℰ",esdot:"≐",Esim:"⩳",esim:"≂",Eta:"Η",eta:"η",ETH:"Ð",eth:"ð",Euml:"Ë",euml:"ë",euro:"€",excl:"!",exist:"∃",Exists:"∃",expectation:"ℰ",exponentiale:"ⅇ",ExponentialE:"ⅇ",fallingdotseq:"≒",Fcy:"Ф",fcy:"ф",female:"♀",ffilig:"ffi",fflig:"ff",ffllig:"ffl",Ffr:"𝔉",ffr:"𝔣",filig:"fi",FilledSmallSquare:"◼",FilledVerySmallSquare:"▪",fjlig:"fj",flat:"♭",fllig:"fl",fltns:"▱",fnof:"ƒ",Fopf:"𝔽",fopf:"𝕗",forall:"∀",ForAll:"∀",fork:"⋔",forkv:"⫙",Fouriertrf:"ℱ",fpartint:"⨍",frac12:"½",frac13:"⅓",frac14:"¼",frac15:"⅕",frac16:"⅙",frac18:"⅛",frac23:"⅔",frac25:"⅖",frac34:"¾",frac35:"⅗",frac38:"⅜",frac45:"⅘",frac56:"⅚",frac58:"⅝",frac78:"⅞",frasl:"⁄",frown:"⌢",fscr:"𝒻",Fscr:"ℱ",gacute:"ǵ",Gamma:"Γ",gamma:"γ",Gammad:"Ϝ",gammad:"ϝ",gap:"⪆",Gbreve:"Ğ",gbreve:"ğ",Gcedil:"Ģ",Gcirc:"Ĝ",gcirc:"ĝ",Gcy:"Г",gcy:"г",Gdot:"Ġ",gdot:"ġ",ge:"≥",gE:"≧",gEl:"⪌",gel:"⋛",geq:"≥",geqq:"≧",geqslant:"⩾",gescc:"⪩",ges:"⩾",gesdot:"⪀",gesdoto:"⪂",gesdotol:"⪄",gesl:"⋛︀",gesles:"⪔",Gfr:"𝔊",gfr:"𝔤",gg:"≫",Gg:"⋙",ggg:"⋙",gimel:"ℷ",GJcy:"Ѓ",gjcy:"ѓ",gla:"⪥",gl:"≷",glE:"⪒",glj:"⪤",gnap:"⪊",gnapprox:"⪊",gne:"⪈",gnE:"≩",gneq:"⪈",gneqq:"≩",gnsim:"⋧",Gopf:"𝔾",gopf:"𝕘",grave:"`",GreaterEqual:"≥",GreaterEqualLess:"⋛",GreaterFullEqual:"≧",GreaterGreater:"⪢",GreaterLess:"≷",GreaterSlantEqual:"⩾",GreaterTilde:"≳",Gscr:"𝒢",gscr:"ℊ",gsim:"≳",gsime:"⪎",gsiml:"⪐",gtcc:"⪧",gtcir:"⩺",gt:">",GT:">",Gt:"≫",gtdot:"⋗",gtlPar:"⦕",gtquest:"⩼",gtrapprox:"⪆",gtrarr:"⥸",gtrdot:"⋗",gtreqless:"⋛",gtreqqless:"⪌",gtrless:"≷",gtrsim:"≳",gvertneqq:"≩︀",gvnE:"≩︀",Hacek:"ˇ",hairsp:" ",half:"½",hamilt:"ℋ",HARDcy:"Ъ",hardcy:"ъ",harrcir:"⥈",harr:"↔",hArr:"⇔",harrw:"↭",Hat:"^",hbar:"ℏ",Hcirc:"Ĥ",hcirc:"ĥ",hearts:"♥",heartsuit:"♥",hellip:"…",hercon:"⊹",hfr:"𝔥",Hfr:"ℌ",HilbertSpace:"ℋ",hksearow:"⤥",hkswarow:"⤦",hoarr:"⇿",homtht:"∻",hookleftarrow:"↩",hookrightarrow:"↪",hopf:"𝕙",Hopf:"ℍ",horbar:"―",HorizontalLine:"─",hscr:"𝒽",Hscr:"ℋ",hslash:"ℏ",Hstrok:"Ħ",hstrok:"ħ",HumpDownHump:"≎",HumpEqual:"≏",hybull:"⁃",hyphen:"‐",Iacute:"Í",iacute:"í",ic:"⁣",Icirc:"Î",icirc:"î",Icy:"И",icy:"и",Idot:"İ",IEcy:"Е",iecy:"е",iexcl:"¡",iff:"⇔",ifr:"𝔦",Ifr:"ℑ",Igrave:"Ì",igrave:"ì",ii:"ⅈ",iiiint:"⨌",iiint:"∭",iinfin:"⧜",iiota:"℩",IJlig:"IJ",ijlig:"ij",Imacr:"Ī",imacr:"ī",image:"ℑ",ImaginaryI:"ⅈ",imagline:"ℐ",imagpart:"ℑ",imath:"ı",Im:"ℑ",imof:"⊷",imped:"Ƶ",Implies:"⇒",incare:"℅",in:"∈",infin:"∞",infintie:"⧝",inodot:"ı",intcal:"⊺",int:"∫",Int:"∬",integers:"ℤ",Integral:"∫",intercal:"⊺",Intersection:"⋂",intlarhk:"⨗",intprod:"⨼",InvisibleComma:"⁣",InvisibleTimes:"⁢",IOcy:"Ё",iocy:"ё",Iogon:"Į",iogon:"į",Iopf:"𝕀",iopf:"𝕚",Iota:"Ι",iota:"ι",iprod:"⨼",iquest:"¿",iscr:"𝒾",Iscr:"ℐ",isin:"∈",isindot:"⋵",isinE:"⋹",isins:"⋴",isinsv:"⋳",isinv:"∈",it:"⁢",Itilde:"Ĩ",itilde:"ĩ",Iukcy:"І",iukcy:"і",Iuml:"Ï",iuml:"ï",Jcirc:"Ĵ",jcirc:"ĵ",Jcy:"Й",jcy:"й",Jfr:"𝔍",jfr:"𝔧",jmath:"ȷ",Jopf:"𝕁",jopf:"𝕛",Jscr:"𝒥",jscr:"𝒿",Jsercy:"Ј",jsercy:"ј",Jukcy:"Є",jukcy:"є",Kappa:"Κ",kappa:"κ",kappav:"ϰ",Kcedil:"Ķ",kcedil:"ķ",Kcy:"К",kcy:"к",Kfr:"𝔎",kfr:"𝔨",kgreen:"ĸ",KHcy:"Х",khcy:"х",KJcy:"Ќ",kjcy:"ќ",Kopf:"𝕂",kopf:"𝕜",Kscr:"𝒦",kscr:"𝓀",lAarr:"⇚",Lacute:"Ĺ",lacute:"ĺ",laemptyv:"⦴",lagran:"ℒ",Lambda:"Λ",lambda:"λ",lang:"⟨",Lang:"⟪",langd:"⦑",langle:"⟨",lap:"⪅",Laplacetrf:"ℒ",laquo:"«",larrb:"⇤",larrbfs:"⤟",larr:"←",Larr:"↞",lArr:"⇐",larrfs:"⤝",larrhk:"↩",larrlp:"↫",larrpl:"⤹",larrsim:"⥳",larrtl:"↢",latail:"⤙",lAtail:"⤛",lat:"⪫",late:"⪭",lates:"⪭︀",lbarr:"⤌",lBarr:"⤎",lbbrk:"❲",lbrace:"{",lbrack:"[",lbrke:"⦋",lbrksld:"⦏",lbrkslu:"⦍",Lcaron:"Ľ",lcaron:"ľ",Lcedil:"Ļ",lcedil:"ļ",lceil:"⌈",lcub:"{",Lcy:"Л",lcy:"л",ldca:"⤶",ldquo:"“",ldquor:"„",ldrdhar:"⥧",ldrushar:"⥋",ldsh:"↲",le:"≤",lE:"≦",LeftAngleBracket:"⟨",LeftArrowBar:"⇤",leftarrow:"←",LeftArrow:"←",Leftarrow:"⇐",LeftArrowRightArrow:"⇆",leftarrowtail:"↢",LeftCeiling:"⌈",LeftDoubleBracket:"⟦",LeftDownTeeVector:"⥡",LeftDownVectorBar:"⥙",LeftDownVector:"⇃",LeftFloor:"⌊",leftharpoondown:"↽",leftharpoonup:"↼",leftleftarrows:"⇇",leftrightarrow:"↔",LeftRightArrow:"↔",Leftrightarrow:"⇔",leftrightarrows:"⇆",leftrightharpoons:"⇋",leftrightsquigarrow:"↭",LeftRightVector:"⥎",LeftTeeArrow:"↤",LeftTee:"⊣",LeftTeeVector:"⥚",leftthreetimes:"⋋",LeftTriangleBar:"⧏",LeftTriangle:"⊲",LeftTriangleEqual:"⊴",LeftUpDownVector:"⥑",LeftUpTeeVector:"⥠",LeftUpVectorBar:"⥘",LeftUpVector:"↿",LeftVectorBar:"⥒",LeftVector:"↼",lEg:"⪋",leg:"⋚",leq:"≤",leqq:"≦",leqslant:"⩽",lescc:"⪨",les:"⩽",lesdot:"⩿",lesdoto:"⪁",lesdotor:"⪃",lesg:"⋚︀",lesges:"⪓",lessapprox:"⪅",lessdot:"⋖",lesseqgtr:"⋚",lesseqqgtr:"⪋",LessEqualGreater:"⋚",LessFullEqual:"≦",LessGreater:"≶",lessgtr:"≶",LessLess:"⪡",lesssim:"≲",LessSlantEqual:"⩽",LessTilde:"≲",lfisht:"⥼",lfloor:"⌊",Lfr:"𝔏",lfr:"𝔩",lg:"≶",lgE:"⪑",lHar:"⥢",lhard:"↽",lharu:"↼",lharul:"⥪",lhblk:"▄",LJcy:"Љ",ljcy:"љ",llarr:"⇇",ll:"≪",Ll:"⋘",llcorner:"⌞",Lleftarrow:"⇚",llhard:"⥫",lltri:"◺",Lmidot:"Ŀ",lmidot:"ŀ",lmoustache:"⎰",lmoust:"⎰",lnap:"⪉",lnapprox:"⪉",lne:"⪇",lnE:"≨",lneq:"⪇",lneqq:"≨",lnsim:"⋦",loang:"⟬",loarr:"⇽",lobrk:"⟦",longleftarrow:"⟵",LongLeftArrow:"⟵",Longleftarrow:"⟸",longleftrightarrow:"⟷",LongLeftRightArrow:"⟷",Longleftrightarrow:"⟺",longmapsto:"⟼",longrightarrow:"⟶",LongRightArrow:"⟶",Longrightarrow:"⟹",looparrowleft:"↫",looparrowright:"↬",lopar:"⦅",Lopf:"𝕃",lopf:"𝕝",loplus:"⨭",lotimes:"⨴",lowast:"∗",lowbar:"_",LowerLeftArrow:"↙",LowerRightArrow:"↘",loz:"◊",lozenge:"◊",lozf:"⧫",lpar:"(",lparlt:"⦓",lrarr:"⇆",lrcorner:"⌟",lrhar:"⇋",lrhard:"⥭",lrm:"‎",lrtri:"⊿",lsaquo:"‹",lscr:"𝓁",Lscr:"ℒ",lsh:"↰",Lsh:"↰",lsim:"≲",lsime:"⪍",lsimg:"⪏",lsqb:"[",lsquo:"‘",lsquor:"‚",Lstrok:"Ł",lstrok:"ł",ltcc:"⪦",ltcir:"⩹",lt:"<",LT:"<",Lt:"≪",ltdot:"⋖",lthree:"⋋",ltimes:"⋉",ltlarr:"⥶",ltquest:"⩻",ltri:"◃",ltrie:"⊴",ltrif:"◂",ltrPar:"⦖",lurdshar:"⥊",luruhar:"⥦",lvertneqq:"≨︀",lvnE:"≨︀",macr:"¯",male:"♂",malt:"✠",maltese:"✠",Map:"⤅",map:"↦",mapsto:"↦",mapstodown:"↧",mapstoleft:"↤",mapstoup:"↥",marker:"▮",mcomma:"⨩",Mcy:"М",mcy:"м",mdash:"—",mDDot:"∺",measuredangle:"∡",MediumSpace:" ",Mellintrf:"ℳ",Mfr:"𝔐",mfr:"𝔪",mho:"℧",micro:"µ",midast:"*",midcir:"⫰",mid:"∣",middot:"·",minusb:"⊟",minus:"−",minusd:"∸",minusdu:"⨪",MinusPlus:"∓",mlcp:"⫛",mldr:"…",mnplus:"∓",models:"⊧",Mopf:"𝕄",mopf:"𝕞",mp:"∓",mscr:"𝓂",Mscr:"ℳ",mstpos:"∾",Mu:"Μ",mu:"μ",multimap:"⊸",mumap:"⊸",nabla:"∇",Nacute:"Ń",nacute:"ń",nang:"∠⃒",nap:"≉",napE:"⩰̸",napid:"≋̸",napos:"ʼn",napprox:"≉",natural:"♮",naturals:"ℕ",natur:"♮",nbsp:" ",nbump:"≎̸",nbumpe:"≏̸",ncap:"⩃",Ncaron:"Ň",ncaron:"ň",Ncedil:"Ņ",ncedil:"ņ",ncong:"≇",ncongdot:"⩭̸",ncup:"⩂",Ncy:"Н",ncy:"н",ndash:"–",nearhk:"⤤",nearr:"↗",neArr:"⇗",nearrow:"↗",ne:"≠",nedot:"≐̸",NegativeMediumSpace:"​",NegativeThickSpace:"​",NegativeThinSpace:"​",NegativeVeryThinSpace:"​",nequiv:"≢",nesear:"⤨",nesim:"≂̸",NestedGreaterGreater:"≫",NestedLessLess:"≪",NewLine:"\n",nexist:"∄",nexists:"∄",Nfr:"𝔑",nfr:"𝔫",ngE:"≧̸",nge:"≱",ngeq:"≱",ngeqq:"≧̸",ngeqslant:"⩾̸",nges:"⩾̸",nGg:"⋙̸",ngsim:"≵",nGt:"≫⃒",ngt:"≯",ngtr:"≯",nGtv:"≫̸",nharr:"↮",nhArr:"⇎",nhpar:"⫲",ni:"∋",nis:"⋼",nisd:"⋺",niv:"∋",NJcy:"Њ",njcy:"њ",nlarr:"↚",nlArr:"⇍",nldr:"‥",nlE:"≦̸",nle:"≰",nleftarrow:"↚",nLeftarrow:"⇍",nleftrightarrow:"↮",nLeftrightarrow:"⇎",nleq:"≰",nleqq:"≦̸",nleqslant:"⩽̸",nles:"⩽̸",nless:"≮",nLl:"⋘̸",nlsim:"≴",nLt:"≪⃒",nlt:"≮",nltri:"⋪",nltrie:"⋬",nLtv:"≪̸",nmid:"∤",NoBreak:"⁠",NonBreakingSpace:" ",nopf:"𝕟",Nopf:"ℕ",Not:"⫬",not:"¬",NotCongruent:"≢",NotCupCap:"≭",NotDoubleVerticalBar:"∦",NotElement:"∉",NotEqual:"≠",NotEqualTilde:"≂̸",NotExists:"∄",NotGreater:"≯",NotGreaterEqual:"≱",NotGreaterFullEqual:"≧̸",NotGreaterGreater:"≫̸",NotGreaterLess:"≹",NotGreaterSlantEqual:"⩾̸",NotGreaterTilde:"≵",NotHumpDownHump:"≎̸",NotHumpEqual:"≏̸",notin:"∉",notindot:"⋵̸",notinE:"⋹̸",notinva:"∉",notinvb:"⋷",notinvc:"⋶",NotLeftTriangleBar:"⧏̸",NotLeftTriangle:"⋪",NotLeftTriangleEqual:"⋬",NotLess:"≮",NotLessEqual:"≰",NotLessGreater:"≸",NotLessLess:"≪̸",NotLessSlantEqual:"⩽̸",NotLessTilde:"≴",NotNestedGreaterGreater:"⪢̸",NotNestedLessLess:"⪡̸",notni:"∌",notniva:"∌",notnivb:"⋾",notnivc:"⋽",NotPrecedes:"⊀",NotPrecedesEqual:"⪯̸",NotPrecedesSlantEqual:"⋠",NotReverseElement:"∌",NotRightTriangleBar:"⧐̸",NotRightTriangle:"⋫",NotRightTriangleEqual:"⋭",NotSquareSubset:"⊏̸",NotSquareSubsetEqual:"⋢",NotSquareSuperset:"⊐̸",NotSquareSupersetEqual:"⋣",NotSubset:"⊂⃒",NotSubsetEqual:"⊈",NotSucceeds:"⊁",NotSucceedsEqual:"⪰̸",NotSucceedsSlantEqual:"⋡",NotSucceedsTilde:"≿̸",NotSuperset:"⊃⃒",NotSupersetEqual:"⊉",NotTilde:"≁",NotTildeEqual:"≄",NotTildeFullEqual:"≇",NotTildeTilde:"≉",NotVerticalBar:"∤",nparallel:"∦",npar:"∦",nparsl:"⫽⃥",npart:"∂̸",npolint:"⨔",npr:"⊀",nprcue:"⋠",nprec:"⊀",npreceq:"⪯̸",npre:"⪯̸",nrarrc:"⤳̸",nrarr:"↛",nrArr:"⇏",nrarrw:"↝̸",nrightarrow:"↛",nRightarrow:"⇏",nrtri:"⋫",nrtrie:"⋭",nsc:"⊁",nsccue:"⋡",nsce:"⪰̸",Nscr:"𝒩",nscr:"𝓃",nshortmid:"∤",nshortparallel:"∦",nsim:"≁",nsime:"≄",nsimeq:"≄",nsmid:"∤",nspar:"∦",nsqsube:"⋢",nsqsupe:"⋣",nsub:"⊄",nsubE:"⫅̸",nsube:"⊈",nsubset:"⊂⃒",nsubseteq:"⊈",nsubseteqq:"⫅̸",nsucc:"⊁",nsucceq:"⪰̸",nsup:"⊅",nsupE:"⫆̸",nsupe:"⊉",nsupset:"⊃⃒",nsupseteq:"⊉",nsupseteqq:"⫆̸",ntgl:"≹",Ntilde:"Ñ",ntilde:"ñ",ntlg:"≸",ntriangleleft:"⋪",ntrianglelefteq:"⋬",ntriangleright:"⋫",ntrianglerighteq:"⋭",Nu:"Ν",nu:"ν",num:"#",numero:"№",numsp:" ",nvap:"≍⃒",nvdash:"⊬",nvDash:"⊭",nVdash:"⊮",nVDash:"⊯",nvge:"≥⃒",nvgt:">⃒",nvHarr:"⤄",nvinfin:"⧞",nvlArr:"⤂",nvle:"≤⃒",nvlt:"<⃒",nvltrie:"⊴⃒",nvrArr:"⤃",nvrtrie:"⊵⃒",nvsim:"∼⃒",nwarhk:"⤣",nwarr:"↖",nwArr:"⇖",nwarrow:"↖",nwnear:"⤧",Oacute:"Ó",oacute:"ó",oast:"⊛",Ocirc:"Ô",ocirc:"ô",ocir:"⊚",Ocy:"О",ocy:"о",odash:"⊝",Odblac:"Ő",odblac:"ő",odiv:"⨸",odot:"⊙",odsold:"⦼",OElig:"Œ",oelig:"œ",ofcir:"⦿",Ofr:"𝔒",ofr:"𝔬",ogon:"˛",Ograve:"Ò",ograve:"ò",ogt:"⧁",ohbar:"⦵",ohm:"Ω",oint:"∮",olarr:"↺",olcir:"⦾",olcross:"⦻",oline:"‾",olt:"⧀",Omacr:"Ō",omacr:"ō",Omega:"Ω",omega:"ω",Omicron:"Ο",omicron:"ο",omid:"⦶",ominus:"⊖",Oopf:"𝕆",oopf:"𝕠",opar:"⦷",OpenCurlyDoubleQuote:"“",OpenCurlyQuote:"‘",operp:"⦹",oplus:"⊕",orarr:"↻",Or:"⩔",or:"∨",ord:"⩝",order:"ℴ",orderof:"ℴ",ordf:"ª",ordm:"º",origof:"⊶",oror:"⩖",orslope:"⩗",orv:"⩛",oS:"Ⓢ",Oscr:"𝒪",oscr:"ℴ",Oslash:"Ø",oslash:"ø",osol:"⊘",Otilde:"Õ",otilde:"õ",otimesas:"⨶",Otimes:"⨷",otimes:"⊗",Ouml:"Ö",ouml:"ö",ovbar:"⌽",OverBar:"‾",OverBrace:"⏞",OverBracket:"⎴",OverParenthesis:"⏜",para:"¶",parallel:"∥",par:"∥",parsim:"⫳",parsl:"⫽",part:"∂",PartialD:"∂",Pcy:"П",pcy:"п",percnt:"%",period:".",permil:"‰",perp:"⊥",pertenk:"‱",Pfr:"𝔓",pfr:"𝔭",Phi:"Φ",phi:"φ",phiv:"ϕ",phmmat:"ℳ",phone:"☎",Pi:"Π",pi:"π",pitchfork:"⋔",piv:"ϖ",planck:"ℏ",planckh:"ℎ",plankv:"ℏ",plusacir:"⨣",plusb:"⊞",pluscir:"⨢",plus:"+",plusdo:"∔",plusdu:"⨥",pluse:"⩲",PlusMinus:"±",plusmn:"±",plussim:"⨦",plustwo:"⨧",pm:"±",Poincareplane:"ℌ",pointint:"⨕",popf:"𝕡",Popf:"ℙ",pound:"£",prap:"⪷",Pr:"⪻",pr:"≺",prcue:"≼",precapprox:"⪷",prec:"≺",preccurlyeq:"≼",Precedes:"≺",PrecedesEqual:"⪯",PrecedesSlantEqual:"≼",PrecedesTilde:"≾",preceq:"⪯",precnapprox:"⪹",precneqq:"⪵",precnsim:"⋨",pre:"⪯",prE:"⪳",precsim:"≾",prime:"′",Prime:"″",primes:"ℙ",prnap:"⪹",prnE:"⪵",prnsim:"⋨",prod:"∏",Product:"∏",profalar:"⌮",profline:"⌒",profsurf:"⌓",prop:"∝",Proportional:"∝",Proportion:"∷",propto:"∝",prsim:"≾",prurel:"⊰",Pscr:"𝒫",pscr:"𝓅",Psi:"Ψ",psi:"ψ",puncsp:" ",Qfr:"𝔔",qfr:"𝔮",qint:"⨌",qopf:"𝕢",Qopf:"ℚ",qprime:"⁗",Qscr:"𝒬",qscr:"𝓆",quaternions:"ℍ",quatint:"⨖",quest:"?",questeq:"≟",quot:'"',QUOT:'"',rAarr:"⇛",race:"∽̱",Racute:"Ŕ",racute:"ŕ",radic:"√",raemptyv:"⦳",rang:"⟩",Rang:"⟫",rangd:"⦒",range:"⦥",rangle:"⟩",raquo:"»",rarrap:"⥵",rarrb:"⇥",rarrbfs:"⤠",rarrc:"⤳",rarr:"→",Rarr:"↠",rArr:"⇒",rarrfs:"⤞",rarrhk:"↪",rarrlp:"↬",rarrpl:"⥅",rarrsim:"⥴",Rarrtl:"⤖",rarrtl:"↣",rarrw:"↝",ratail:"⤚",rAtail:"⤜",ratio:"∶",rationals:"ℚ",rbarr:"⤍",rBarr:"⤏",RBarr:"⤐",rbbrk:"❳",rbrace:"}",rbrack:"]",rbrke:"⦌",rbrksld:"⦎",rbrkslu:"⦐",Rcaron:"Ř",rcaron:"ř",Rcedil:"Ŗ",rcedil:"ŗ",rceil:"⌉",rcub:"}",Rcy:"Р",rcy:"р",rdca:"⤷",rdldhar:"⥩",rdquo:"”",rdquor:"”",rdsh:"↳",real:"ℜ",realine:"ℛ",realpart:"ℜ",reals:"ℝ",Re:"ℜ",rect:"▭",reg:"®",REG:"®",ReverseElement:"∋",ReverseEquilibrium:"⇋",ReverseUpEquilibrium:"⥯",rfisht:"⥽",rfloor:"⌋",rfr:"𝔯",Rfr:"ℜ",rHar:"⥤",rhard:"⇁",rharu:"⇀",rharul:"⥬",Rho:"Ρ",rho:"ρ",rhov:"ϱ",RightAngleBracket:"⟩",RightArrowBar:"⇥",rightarrow:"→",RightArrow:"→",Rightarrow:"⇒",RightArrowLeftArrow:"⇄",rightarrowtail:"↣",RightCeiling:"⌉",RightDoubleBracket:"⟧",RightDownTeeVector:"⥝",RightDownVectorBar:"⥕",RightDownVector:"⇂",RightFloor:"⌋",rightharpoondown:"⇁",rightharpoonup:"⇀",rightleftarrows:"⇄",rightleftharpoons:"⇌",rightrightarrows:"⇉",rightsquigarrow:"↝",RightTeeArrow:"↦",RightTee:"⊢",RightTeeVector:"⥛",rightthreetimes:"⋌",RightTriangleBar:"⧐",RightTriangle:"⊳",RightTriangleEqual:"⊵",RightUpDownVector:"⥏",RightUpTeeVector:"⥜",RightUpVectorBar:"⥔",RightUpVector:"↾",RightVectorBar:"⥓",RightVector:"⇀",ring:"˚",risingdotseq:"≓",rlarr:"⇄",rlhar:"⇌",rlm:"‏",rmoustache:"⎱",rmoust:"⎱",rnmid:"⫮",roang:"⟭",roarr:"⇾",robrk:"⟧",ropar:"⦆",ropf:"𝕣",Ropf:"ℝ",roplus:"⨮",rotimes:"⨵",RoundImplies:"⥰",rpar:")",rpargt:"⦔",rppolint:"⨒",rrarr:"⇉",Rrightarrow:"⇛",rsaquo:"›",rscr:"𝓇",Rscr:"ℛ",rsh:"↱",Rsh:"↱",rsqb:"]",rsquo:"’",rsquor:"’",rthree:"⋌",rtimes:"⋊",rtri:"▹",rtrie:"⊵",rtrif:"▸",rtriltri:"⧎",RuleDelayed:"⧴",ruluhar:"⥨",rx:"℞",Sacute:"Ś",sacute:"ś",sbquo:"‚",scap:"⪸",Scaron:"Š",scaron:"š",Sc:"⪼",sc:"≻",sccue:"≽",sce:"⪰",scE:"⪴",Scedil:"Ş",scedil:"ş",Scirc:"Ŝ",scirc:"ŝ",scnap:"⪺",scnE:"⪶",scnsim:"⋩",scpolint:"⨓",scsim:"≿",Scy:"С",scy:"с",sdotb:"⊡",sdot:"⋅",sdote:"⩦",searhk:"⤥",searr:"↘",seArr:"⇘",searrow:"↘",sect:"§",semi:";",seswar:"⤩",setminus:"∖",setmn:"∖",sext:"✶",Sfr:"𝔖",sfr:"𝔰",sfrown:"⌢",sharp:"♯",SHCHcy:"Щ",shchcy:"щ",SHcy:"Ш",shcy:"ш",ShortDownArrow:"↓",ShortLeftArrow:"←",shortmid:"∣",shortparallel:"∥",ShortRightArrow:"→",ShortUpArrow:"↑",shy:"­",Sigma:"Σ",sigma:"σ",sigmaf:"ς",sigmav:"ς",sim:"∼",simdot:"⩪",sime:"≃",simeq:"≃",simg:"⪞",simgE:"⪠",siml:"⪝",simlE:"⪟",simne:"≆",simplus:"⨤",simrarr:"⥲",slarr:"←",SmallCircle:"∘",smallsetminus:"∖",smashp:"⨳",smeparsl:"⧤",smid:"∣",smile:"⌣",smt:"⪪",smte:"⪬",smtes:"⪬︀",SOFTcy:"Ь",softcy:"ь",solbar:"⌿",solb:"⧄",sol:"/",Sopf:"𝕊",sopf:"𝕤",spades:"♠",spadesuit:"♠",spar:"∥",sqcap:"⊓",sqcaps:"⊓︀",sqcup:"⊔",sqcups:"⊔︀",Sqrt:"√",sqsub:"⊏",sqsube:"⊑",sqsubset:"⊏",sqsubseteq:"⊑",sqsup:"⊐",sqsupe:"⊒",sqsupset:"⊐",sqsupseteq:"⊒",square:"□",Square:"□",SquareIntersection:"⊓",SquareSubset:"⊏",SquareSubsetEqual:"⊑",SquareSuperset:"⊐",SquareSupersetEqual:"⊒",SquareUnion:"⊔",squarf:"▪",squ:"□",squf:"▪",srarr:"→",Sscr:"𝒮",sscr:"𝓈",ssetmn:"∖",ssmile:"⌣",sstarf:"⋆",Star:"⋆",star:"☆",starf:"★",straightepsilon:"ϵ",straightphi:"ϕ",strns:"¯",sub:"⊂",Sub:"⋐",subdot:"⪽",subE:"⫅",sube:"⊆",subedot:"⫃",submult:"⫁",subnE:"⫋",subne:"⊊",subplus:"⪿",subrarr:"⥹",subset:"⊂",Subset:"⋐",subseteq:"⊆",subseteqq:"⫅",SubsetEqual:"⊆",subsetneq:"⊊",subsetneqq:"⫋",subsim:"⫇",subsub:"⫕",subsup:"⫓",succapprox:"⪸",succ:"≻",succcurlyeq:"≽",Succeeds:"≻",SucceedsEqual:"⪰",SucceedsSlantEqual:"≽",SucceedsTilde:"≿",succeq:"⪰",succnapprox:"⪺",succneqq:"⪶",succnsim:"⋩",succsim:"≿",SuchThat:"∋",sum:"∑",Sum:"∑",sung:"♪",sup1:"¹",sup2:"²",sup3:"³",sup:"⊃",Sup:"⋑",supdot:"⪾",supdsub:"⫘",supE:"⫆",supe:"⊇",supedot:"⫄",Superset:"⊃",SupersetEqual:"⊇",suphsol:"⟉",suphsub:"⫗",suplarr:"⥻",supmult:"⫂",supnE:"⫌",supne:"⊋",supplus:"⫀",supset:"⊃",Supset:"⋑",supseteq:"⊇",supseteqq:"⫆",supsetneq:"⊋",supsetneqq:"⫌",supsim:"⫈",supsub:"⫔",supsup:"⫖",swarhk:"⤦",swarr:"↙",swArr:"⇙",swarrow:"↙",swnwar:"⤪",szlig:"ß",Tab:"\t",target:"⌖",Tau:"Τ",tau:"τ",tbrk:"⎴",Tcaron:"Ť",tcaron:"ť",Tcedil:"Ţ",tcedil:"ţ",Tcy:"Т",tcy:"т",tdot:"⃛",telrec:"⌕",Tfr:"𝔗",tfr:"𝔱",there4:"∴",therefore:"∴",Therefore:"∴",Theta:"Θ",theta:"θ",thetasym:"ϑ",thetav:"ϑ",thickapprox:"≈",thicksim:"∼",ThickSpace:"  ",ThinSpace:" ",thinsp:" ",thkap:"≈",thksim:"∼",THORN:"Þ",thorn:"þ",tilde:"˜",Tilde:"∼",TildeEqual:"≃",TildeFullEqual:"≅",TildeTilde:"≈",timesbar:"⨱",timesb:"⊠",times:"×",timesd:"⨰",tint:"∭",toea:"⤨",topbot:"⌶",topcir:"⫱",top:"⊤",Topf:"𝕋",topf:"𝕥",topfork:"⫚",tosa:"⤩",tprime:"‴",trade:"™",TRADE:"™",triangle:"▵",triangledown:"▿",triangleleft:"◃",trianglelefteq:"⊴",triangleq:"≜",triangleright:"▹",trianglerighteq:"⊵",tridot:"◬",trie:"≜",triminus:"⨺",TripleDot:"⃛",triplus:"⨹",trisb:"⧍",tritime:"⨻",trpezium:"⏢",Tscr:"𝒯",tscr:"𝓉",TScy:"Ц",tscy:"ц",TSHcy:"Ћ",tshcy:"ћ",Tstrok:"Ŧ",tstrok:"ŧ",twixt:"≬",twoheadleftarrow:"↞",twoheadrightarrow:"↠",Uacute:"Ú",uacute:"ú",uarr:"↑",Uarr:"↟",uArr:"⇑",Uarrocir:"⥉",Ubrcy:"Ў",ubrcy:"ў",Ubreve:"Ŭ",ubreve:"ŭ",Ucirc:"Û",ucirc:"û",Ucy:"У",ucy:"у",udarr:"⇅",Udblac:"Ű",udblac:"ű",udhar:"⥮",ufisht:"⥾",Ufr:"𝔘",ufr:"𝔲",Ugrave:"Ù",ugrave:"ù",uHar:"⥣",uharl:"↿",uharr:"↾",uhblk:"▀",ulcorn:"⌜",ulcorner:"⌜",ulcrop:"⌏",ultri:"◸",Umacr:"Ū",umacr:"ū",uml:"¨",UnderBar:"_",UnderBrace:"⏟",UnderBracket:"⎵",UnderParenthesis:"⏝",Union:"⋃",UnionPlus:"⊎",Uogon:"Ų",uogon:"ų",Uopf:"𝕌",uopf:"𝕦",UpArrowBar:"⤒",uparrow:"↑",UpArrow:"↑",Uparrow:"⇑",UpArrowDownArrow:"⇅",updownarrow:"↕",UpDownArrow:"↕",Updownarrow:"⇕",UpEquilibrium:"⥮",upharpoonleft:"↿",upharpoonright:"↾",uplus:"⊎",UpperLeftArrow:"↖",UpperRightArrow:"↗",upsi:"υ",Upsi:"ϒ",upsih:"ϒ",Upsilon:"Υ",upsilon:"υ",UpTeeArrow:"↥",UpTee:"⊥",upuparrows:"⇈",urcorn:"⌝",urcorner:"⌝",urcrop:"⌎",Uring:"Ů",uring:"ů",urtri:"◹",Uscr:"𝒰",uscr:"𝓊",utdot:"⋰",Utilde:"Ũ",utilde:"ũ",utri:"▵",utrif:"▴",uuarr:"⇈",Uuml:"Ü",uuml:"ü",uwangle:"⦧",vangrt:"⦜",varepsilon:"ϵ",varkappa:"ϰ",varnothing:"∅",varphi:"ϕ",varpi:"ϖ",varpropto:"∝",varr:"↕",vArr:"⇕",varrho:"ϱ",varsigma:"ς",varsubsetneq:"⊊︀",varsubsetneqq:"⫋︀",varsupsetneq:"⊋︀",varsupsetneqq:"⫌︀",vartheta:"ϑ",vartriangleleft:"⊲",vartriangleright:"⊳",vBar:"⫨",Vbar:"⫫",vBarv:"⫩",Vcy:"В",vcy:"в",vdash:"⊢",vDash:"⊨",Vdash:"⊩",VDash:"⊫",Vdashl:"⫦",veebar:"⊻",vee:"∨",Vee:"⋁",veeeq:"≚",vellip:"⋮",verbar:"|",Verbar:"‖",vert:"|",Vert:"‖",VerticalBar:"∣",VerticalLine:"|",VerticalSeparator:"❘",VerticalTilde:"≀",VeryThinSpace:" ",Vfr:"𝔙",vfr:"𝔳",vltri:"⊲",vnsub:"⊂⃒",vnsup:"⊃⃒",Vopf:"𝕍",vopf:"𝕧",vprop:"∝",vrtri:"⊳",Vscr:"𝒱",vscr:"𝓋",vsubnE:"⫋︀",vsubne:"⊊︀",vsupnE:"⫌︀",vsupne:"⊋︀",Vvdash:"⊪",vzigzag:"⦚",Wcirc:"Ŵ",wcirc:"ŵ",wedbar:"⩟",wedge:"∧",Wedge:"⋀",wedgeq:"≙",weierp:"℘",Wfr:"𝔚",wfr:"𝔴",Wopf:"𝕎",wopf:"𝕨",wp:"℘",wr:"≀",wreath:"≀",Wscr:"𝒲",wscr:"𝓌",xcap:"⋂",xcirc:"◯",xcup:"⋃",xdtri:"▽",Xfr:"𝔛",xfr:"𝔵",xharr:"⟷",xhArr:"⟺",Xi:"Ξ",xi:"ξ",xlarr:"⟵",xlArr:"⟸",xmap:"⟼",xnis:"⋻",xodot:"⨀",Xopf:"𝕏",xopf:"𝕩",xoplus:"⨁",xotime:"⨂",xrarr:"⟶",xrArr:"⟹",Xscr:"𝒳",xscr:"𝓍",xsqcup:"⨆",xuplus:"⨄",xutri:"△",xvee:"⋁",xwedge:"⋀",Yacute:"Ý",yacute:"ý",YAcy:"Я",yacy:"я",Ycirc:"Ŷ",ycirc:"ŷ",Ycy:"Ы",ycy:"ы",yen:"¥",Yfr:"𝔜",yfr:"𝔶",YIcy:"Ї",yicy:"ї",Yopf:"𝕐",yopf:"𝕪",Yscr:"𝒴",yscr:"𝓎",YUcy:"Ю",yucy:"ю",yuml:"ÿ",Yuml:"Ÿ",Zacute:"Ź",zacute:"ź",Zcaron:"Ž",zcaron:"ž",Zcy:"З",zcy:"з",Zdot:"Ż",zdot:"ż",zeetrf:"ℨ",ZeroWidthSpace:"​",Zeta:"Ζ",zeta:"ζ",zfr:"𝔷",Zfr:"ℨ",ZHcy:"Ж",zhcy:"ж",zigrarr:"⇝",zopf:"𝕫",Zopf:"ℤ",Zscr:"𝒵",zscr:"𝓏",zwj:"‍",zwnj:"‌"},Su=/[!-#%-\*,-\/:;\?@\[-\]_\{\}\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166D\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4E\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]|\uD800[\uDD00-\uDD02\uDF9F\uDFD0]|\uD801\uDD6F|\uD802[\uDC57\uDD1F\uDD3F\uDE50-\uDE58\uDE7F\uDEF0-\uDEF6\uDF39-\uDF3F\uDF99-\uDF9C]|\uD803[\uDF55-\uDF59]|\uD804[\uDC47-\uDC4D\uDCBB\uDCBC\uDCBE-\uDCC1\uDD40-\uDD43\uDD74\uDD75\uDDC5-\uDDC8\uDDCD\uDDDB\uDDDD-\uDDDF\uDE38-\uDE3D\uDEA9]|\uD805[\uDC4B-\uDC4F\uDC5B\uDC5D\uDCC6\uDDC1-\uDDD7\uDE41-\uDE43\uDE60-\uDE6C\uDF3C-\uDF3E]|\uD806[\uDC3B\uDE3F-\uDE46\uDE9A-\uDE9C\uDE9E-\uDEA2]|\uD807[\uDC41-\uDC45\uDC70\uDC71\uDEF7\uDEF8]|\uD809[\uDC70-\uDC74]|\uD81A[\uDE6E\uDE6F\uDEF5\uDF37-\uDF3B\uDF44]|\uD81B[\uDE97-\uDE9A]|\uD82F\uDC9F|\uD836[\uDE87-\uDE8B]|\uD83A[\uDD5E\uDD5F]/,Ir={},e2={};function Ns(t,e,n){var r,o,a,s,i,l="";for("string"!=typeof e&&(n=e,e=Ns.defaultChars),typeof n>"u"&&(n=!0),i=function(t){var e,n,r=e2[t];if(r)return r;for(r=e2[t]=[],e=0;e<128;e++)n=String.fromCharCode(e),/^[0-9a-z]$/i.test(n)?r.push(n):r.push("%"+("0"+e.toString(16).toUpperCase()).slice(-2));for(e=0;e=55296&&a<=57343){if(a>=55296&&a<=56319&&r+1=56320&&s<=57343)){l+=encodeURIComponent(t[r]+t[r+1]),r++;continue}l+="%EF%BF%BD"}else l+=encodeURIComponent(t[r]);return l}Ns.defaultChars=";/?:@&=+$,-_.!~*'()#",Ns.componentChars="-_.!~*'()";var O_=Ns,t2={};function Ts(t,e){var n;return"string"!=typeof e&&(e=Ts.defaultChars),n=function(t){var e,n,r=t2[t];if(r)return r;for(r=t2[t]=[],e=0;e<128;e++)n=String.fromCharCode(e),r.push(n);for(e=0;e=55296&&c<=57343?"���":String.fromCharCode(c),o+=6):240==(248&s)&&o+91114111?p+="����":(c-=65536,p+=String.fromCharCode(55296+(c>>10),56320+(1023&c))),o+=9):p+="�";return p}))}Ts.defaultChars=";/?:@&=+$,#",Ts.componentChars="";var I_=Ts;function ws(){this.protocol=null,this.slashes=null,this.auth=null,this.port=null,this.hostname=null,this.hash=null,this.search=null,this.pathname=null}var F_=/^([a-z0-9.+-]+:)/i,B_=/:[0-9]*$/,P_=/^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/,q_=["{","}","|","\\","^","`"].concat(["<",">",'"',"`"," ","\r","\n","\t"]),H_=["'"].concat(q_),n2=["%","/","?",";","#"].concat(H_),r2=["/","?","#"],o2=/^[+a-z0-9A-Z_-]{0,63}$/,$_=/^([+a-z0-9A-Z_-]{0,63})(.*)$/,a2={javascript:!0,"javascript:":!0},s2={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,"http:":!0,"https:":!0,"ftp:":!0,"gopher:":!0,"file:":!0};ws.prototype.parse=function(t,e){var n,r,o,a,s,i=t;if(i=i.trim(),!e&&1===t.split("#").length){var l=P_.exec(i);if(l)return this.pathname=l[1],l[2]&&(this.search=l[2]),this}var u=F_.exec(i);if(u&&(o=(u=u[0]).toLowerCase(),this.protocol=u,i=i.substr(u.length)),(e||u||i.match(/^\/\/[^@\/]+@[^@\/]+/))&&((s="//"===i.substr(0,2))&&!(u&&a2[u])&&(i=i.substr(2),this.slashes=!0)),!a2[u]&&(s||u&&!s2[u])){var p,d,c=-1;for(n=0;n127?h+="x":h+=y[g];if(!h.match(o2)){var _=A.slice(0,n),N=A.slice(n+1),v=y.match($_);v&&(_.push(v[1]),N.unshift(v[2])),N.length&&(i=N.join(".")+i),this.hostname=_.join(".");break}}}}this.hostname.length>255&&(this.hostname=""),b&&(this.hostname=this.hostname.substr(1,this.hostname.length-2))}var T=i.indexOf("#");-1!==T&&(this.hash=i.substr(T),i=i.slice(0,T));var R=i.indexOf("?");return-1!==R&&(this.search=i.substr(R),i=i.slice(0,R)),i&&(this.pathname=i),s2[o]&&this.hostname&&!this.pathname&&(this.pathname=""),this},ws.prototype.parseHost=function(t){var e=B_.exec(t);e&&(":"!==(e=e[0])&&(this.port=e.substr(1)),t=t.substr(0,t.length-e.length)),t&&(this.hostname=t)};var G_=function(t,e){if(t&&t instanceof ws)return t;var n=new ws;return n.parse(t,e),n};Ir.encode=O_,Ir.decode=I_,Ir.format=function(e){var n="";return n+=e.protocol||"",n+=e.slashes?"//":"",n+=e.auth?e.auth+"@":"",e.hostname&&-1!==e.hostname.indexOf(":")?n+="["+e.hostname+"]":n+=e.hostname||"",n+=e.port?":"+e.port:"",n+=e.pathname||"",n+=e.search||"",n+=e.hash||""},Ir.parse=G_;var Nu,i2,Tu,u2,wu,d2,xu,p2,m2,Yn={};function l2(){return i2||(i2=1,Nu=/[\0-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/),Nu}function c2(){return u2||(u2=1,Tu=/[\0-\x1F\x7F-\x9F]/),Tu}function f2(){return p2||(p2=1,xu=/[ \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]/),xu}function j_(){return m2||(m2=1,Yn.Any=l2(),Yn.Cc=c2(),Yn.Cf=(d2||(d2=1,wu=/[\xAD\u0600-\u0605\u061C\u06DD\u070F\u08E2\u180E\u200B-\u200F\u202A-\u202E\u2060-\u2064\u2066-\u206F\uFEFF\uFFF9-\uFFFB]|\uD804[\uDCBD\uDCCD]|\uD82F[\uDCA0-\uDCA3]|\uD834[\uDD73-\uDD7A]|\uDB40[\uDC01\uDC20-\uDC7F]/),wu),Yn.P=Su,Yn.Z=f2()),Yn}!function(t){var r=Object.prototype.hasOwnProperty;function o(O,V){return r.call(O,V)}function i(O){return!(O>=55296&&O<=57343||O>=64976&&O<=65007||65535==(65535&O)||65534==(65535&O)||O>=0&&O<=8||11===O||O>=14&&O<=31||O>=127&&O<=159||O>1114111)}function l(O){if(O>65535){var V=55296+((O-=65536)>>10),B=56320+(1023&O);return String.fromCharCode(V,B)}return String.fromCharCode(O)}var u=/\\([!"#$%&'()*+,\-.\/:;<=>?@[\\\]^_`{|}~])/g,p=new RegExp(u.source+"|"+/&([a-z#][a-z0-9]{1,31});/gi.source,"gi"),d=/^#((?:x[a-f0-9]{1,8}|[0-9]{1,8}))$/i,f=Jf;var h=/[&<>"]/,g=/[&<>"]/g,E={"&":"&","<":"<",">":">",'"':"""};function _(O){return E[O]}var v=/[.?*+^$[\]\\(){}|-]/g;var I=Su;t.lib={},t.lib.mdurl=Ir,t.lib.ucmicro=j_(),t.assign=function(O){return Array.prototype.slice.call(arguments,1).forEach((function(B){if(B){if("object"!=typeof B)throw new TypeError(B+"must be object");Object.keys(B).forEach((function(x){O[x]=B[x]}))}})),O},t.isString=function(O){return"[object String]"===function(O){return Object.prototype.toString.call(O)}(O)},t.has=o,t.unescapeMd=function(O){return O.indexOf("\\")<0?O:O.replace(u,"$1")},t.unescapeAll=function(O){return O.indexOf("\\")<0&&O.indexOf("&")<0?O:O.replace(p,(function(V,B,x){return B||function(O,V){var B;return o(f,V)?f[V]:35===V.charCodeAt(0)&&d.test(V)&&i(B="x"===V[1].toLowerCase()?parseInt(V.slice(2),16):parseInt(V.slice(1),10))?l(B):O}(V,x)}))},t.isValidEntityCode=i,t.fromCodePoint=l,t.escapeHtml=function(O){return h.test(O)?O.replace(g,_):O},t.arrayReplaceAt=function(O,V,B){return[].concat(O.slice(0,V),B,O.slice(V+1))},t.isSpace=function(O){switch(O){case 9:case 32:return!0}return!1},t.isWhiteSpace=function(O){if(O>=8192&&O<=8202)return!0;switch(O){case 9:case 10:case 11:case 12:case 13:case 32:case 160:case 5760:case 8239:case 8287:case 12288:return!0}return!1},t.isMdAsciiPunct=function(O){switch(O){case 33:case 34:case 35:case 36:case 37:case 38:case 39:case 40:case 41:case 42:case 43:case 44:case 45:case 46:case 47:case 58:case 59:case 60:case 61:case 62:case 63:case 64:case 91:case 92:case 93:case 94:case 95:case 96:case 123:case 124:case 125:case 126:return!0;default:return!1}},t.isPunctChar=function(O){return I.test(O)},t.escapeRE=function(O){return O.replace(v,"\\$&")},t.normalizeReference=function(O){return O=O.trim().replace(/\s+/g," "),"Ṿ"==="ẞ".toLowerCase()&&(O=O.replace(/ẞ/g,"ß")),O.toLowerCase().toUpperCase()}}(ie);var xs={},g2=ie.unescapeAll,Y_=ie.unescapeAll;xs.parseLinkLabel=function(e,n,r){var o,a,s,i,l=-1,u=e.posMax,c=e.pos;for(e.pos=n+1,o=1;e.pos32)return i;if(41===o){if(0===a)break;a--}s++}return n===s||0!==a||(i.str=g2(e.slice(n,s)),i.pos=s,i.ok=!0),i},xs.parseLinkTitle=function(e,n,r){var o,a,s=0,i=n,l={ok:!1,pos:0,lines:0,str:""};if(i>=r||34!==(a=e.charCodeAt(i))&&39!==a&&40!==a)return l;for(i++,40===a&&(a=41);i"+Xn(a.content)+""},jt.code_block=function(t,e,n,r,o){var a=t[e];return""+Xn(t[e].content)+"\n"},jt.fence=function(t,e,n,r,o){var u,c,p,d,f,a=t[e],s=a.info?J_(a.info).trim():"",i="",l="";return s&&(i=(p=s.split(/(\s+)/g))[0],l=p.slice(2).join("")),0===(u=n.highlight&&n.highlight(a.content,i,l)||Xn(a.content)).indexOf(""+u+"\n"):"
"+u+"
\n"},jt.image=function(t,e,n,r,o){var a=t[e];return a.attrs[a.attrIndex("alt")][1]=o.renderInlineAsText(a.children,n,r),o.renderToken(t,e,n)},jt.hardbreak=function(t,e,n){return n.xhtmlOut?"
\n":"
\n"},jt.softbreak=function(t,e,n){return n.breaks?n.xhtmlOut?"
\n":"
\n":"\n"},jt.text=function(t,e){return Xn(t[e].content)},jt.html_block=function(t,e){return t[e].content},jt.html_inline=function(t,e){return t[e].content},Mr.prototype.renderAttrs=function(e){var n,r,o;if(!e.attrs)return"";for(o="",n=0,r=e.attrs.length;n\n":">")},Mr.prototype.renderInline=function(t,e,n){for(var r,o="",a=this.rules,s=0,i=t.length;s\s]/i.test(t)}function lv(t){return/^<\/a\s*>/i.test(t)}var h2=/\+-|\.\.|\?\?\?\?|!!!!|,,|--/,cv=/\((c|tm|r)\)/i,dv=/\((c|tm|r)\)/gi,pv={c:"©",r:"®",tm:"™"};function fv(t,e){return pv[e.toLowerCase()]}function mv(t){var e,n,r=0;for(e=t.length-1;e>=0;e--)"text"===(n=t[e]).type&&!r&&(n.content=n.content.replace(dv,fv)),"link_open"===n.type&&"auto"===n.info&&r--,"link_close"===n.type&&"auto"===n.info&&r++}function gv(t){var e,n,r=0;for(e=t.length-1;e>=0;e--)"text"===(n=t[e]).type&&!r&&h2.test(n.content)&&(n.content=n.content.replace(/\+-/g,"±").replace(/\.{2,}/g,"…").replace(/([?!])…/g,"$1..").replace(/([?!]){4,}/g,"$1$1$1").replace(/,{2,}/g,",").replace(/(^|[^-])---(?=[^-]|$)/gm,"$1—").replace(/(^|\s)--(?=\s|$)/gm,"$1–").replace(/(^|[^-\s])--(?=[^-\s]|$)/gm,"$1–")),"link_open"===n.type&&"auto"===n.info&&r--,"link_close"===n.type&&"auto"===n.info&&r++}var E2=ie.isWhiteSpace,b2=ie.isPunctChar,A2=ie.isMdAsciiPunct,Ev=/['"]/,_2=/['"]/g;function Rs(t,e,n){return t.slice(0,e)+n+t.slice(e+1)}function bv(t,e){var n,r,o,a,s,i,l,u,c,p,d,f,b,A,y,h,g,E,_,N,v;for(_=[],n=0;n=0&&!(_[g].level<=l);g--);if(_.length=g+1,"text"===r.type){s=0,i=(o=r.content).length;e:for(;s=0)c=o.charCodeAt(a.index-1);else for(g=n-1;g>=0&&"softbreak"!==t[g].type&&"hardbreak"!==t[g].type;g--)if(t[g].content){c=t[g].content.charCodeAt(t[g].content.length-1);break}if(p=32,s=48&&c<=57&&(h=y=!1),y&&h&&(y=d,h=f),y||h){if(h)for(g=_.length-1;g>=0&&(u=_[g],!(_[g].level=0&&(r=this.attrs[n][1]),r},Fr.prototype.attrJoin=function(e,n){var r=this.attrIndex(e);r<0?this.attrPush([e,n]):this.attrs[r][1]=this.attrs[r][1]+" "+n};var Lu=Fr,vv=Lu;function y2(t,e,n){this.src=t,this.env=n,this.tokens=[],this.inlineMode=!1,this.md=e}y2.prototype.Token=vv;var yv=y2,Dv=Ru,Ou=[["normalize",function(e){var n;n=(n=e.src.replace(tv,"\n")).replace(nv,"�"),e.src=n}],["block",function(e){var n;e.inlineMode?((n=new e.Token("inline","",0)).content=e.src,n.map=[0,1],n.children=[],e.tokens.push(n)):e.md.block.parse(e.src,e.md,e.env,e.tokens)}],["inline",function(e){var r,o,a,n=e.tokens;for(o=0,a=n.length;o=0;n--)if("link_close"!==(i=a[n]).type){if("html_inline"===i.type&&(iv(i.content)&&b>0&&b--,lv(i.content)&&b++),!(b>0)&&"text"===i.type&&e.md.linkify.test(i.content)){for(c=i.content,E=e.md.linkify.match(c),l=[],f=i.level,d=0,E.length>0&&0===E[0].index&&n>0&&"text_special"===a[n-1].type&&(E=E.slice(1)),u=0;ud&&((s=new e.Token("text","",0)).content=c.slice(d,p),s.level=f,l.push(s)),(s=new e.Token("link_open","a",1)).attrs=[["href",y]],s.level=f++,s.markup="linkify",s.info="auto",l.push(s),(s=new e.Token("text","",0)).content=h,s.level=f,l.push(s),(s=new e.Token("link_close","a",-1)).level=--f,s.markup="linkify",s.info="auto",l.push(s),d=E[u].lastIndex);d=0;n--)"inline"===e.tokens[n].type&&(cv.test(e.tokens[n].content)&&mv(e.tokens[n].children),h2.test(e.tokens[n].content)&&gv(e.tokens[n].children))}],["smartquotes",function(e){var n;if(e.md.options.typographer)for(n=e.tokens.length-1;n>=0;n--)"inline"!==e.tokens[n].type||!Ev.test(e.tokens[n].content)||bv(e.tokens[n].children,e)}],["text_join",function(e){var n,r,o,a,s,i,l=e.tokens;for(n=0,r=l.length;n=a||((n=t.src.charCodeAt(o++))<48||n>57))return-1;for(;;){if(o>=a)return-1;if(!((n=t.src.charCodeAt(o++))>=48&&n<=57)){if(41===n||46===n)break;return-1}if(o-r>=10)return-1}return o`\\x00-\\x20]+|'[^']*'|\"[^\"]*\"))?)*\\s*\\/?>",w2="<\\/[A-Za-z][A-Za-z0-9\\-]*\\s*>",jv=new RegExp("^(?:"+T2+"|"+w2+"|\x3c!----\x3e|\x3c!--(?:-?[^>-])(?:-?[^-])*--\x3e|<[?][\\s\\S]*?[?]>|]*>|)"),Wv=new RegExp("^(?:"+T2+"|"+w2+")");Os.HTML_TAG_RE=jv,Os.HTML_OPEN_CLOSE_TAG_RE=Wv;var Kv=["address","article","aside","base","basefont","blockquote","body","caption","center","col","colgroup","dd","details","dialog","dir","div","dl","dt","fieldset","figcaption","figure","footer","form","frame","frameset","h1","h2","h3","h4","h5","h6","head","header","hr","html","iframe","legend","li","link","main","menu","menuitem","nav","noframes","ol","optgroup","option","p","param","section","source","summary","table","tbody","td","tfoot","th","thead","title","tr","track","ul"],Yv=Os.HTML_OPEN_CLOSE_TAG_RE,Br=[[/^<(script|pre|style|textarea)(?=(\s|>|$))/i,/<\/(script|pre|style|textarea)>/i,!0],[/^/,!0],[/^<\?/,/\?>/,!0],[/^/,!0],[/^/,!0],[new RegExp("^|$))","i"),/^$/,!0],[new RegExp(Yv.source+"\\s*$"),/^$/,!1]],x2=ie.isSpace,R2=Lu,ks=ie.isSpace;function Wt(t,e,n,r){var o,a,s,i,l,u,c,p;for(this.src=t,this.md=e,this.env=n,this.tokens=r,this.bMarks=[],this.eMarks=[],this.tShift=[],this.sCount=[],this.bsCount=[],this.blkIndent=0,this.line=0,this.lineMax=0,this.tight=!1,this.ddIndent=-1,this.listIndent=-1,this.parentType="root",this.level=0,this.result="",p=!1,s=i=u=c=0,l=(a=this.src).length;i0&&this.level++,this.tokens.push(r),r},Wt.prototype.isEmpty=function(e){return this.bMarks[e]+this.tShift[e]>=this.eMarks[e]},Wt.prototype.skipEmptyLines=function(e){for(var n=this.lineMax;en;)if(!ks(this.src.charCodeAt(--e)))return e+1;return e},Wt.prototype.skipChars=function(e,n){for(var r=this.src.length;er;)if(n!==this.src.charCodeAt(--e))return e+1;return e},Wt.prototype.getLines=function(e,n,r,o){var a,s,i,l,u,c,p,d=e;if(e>=n)return"";for(c=new Array(n-e),a=0;dr?new Array(s-r+1).join(" ")+this.src.slice(l,u):this.src.slice(l,u)}return c.join("")},Wt.prototype.Token=R2;var ty=Wt,ny=Ru,Is=[["table",function(e,n,r,o){var a,s,i,l,u,c,p,d,f,b,A,y,h,g,E,_,N,v;if(n+2>r||(c=n+1,e.sCount[c]=4||(i=e.bMarks[c]+e.tShift[c])>=e.eMarks[c]||124!==(N=e.src.charCodeAt(i++))&&45!==N&&58!==N||i>=e.eMarks[c]||124!==(v=e.src.charCodeAt(i++))&&45!==v&&58!==v&&!Iu(v)||45===N&&Iu(v))return!1;for(;i=4||((p=D2(s)).length&&""===p[0]&&p.shift(),p.length&&""===p[p.length-1]&&p.pop(),0===(d=p.length)||d!==b.length))return!1;if(o)return!0;for(g=e.parentType,e.parentType="table",_=e.md.block.ruler.getRules("blockquote"),(f=e.push("table_open","table",1)).map=y=[n,0],(f=e.push("thead_open","thead",1)).map=[n,n+1],(f=e.push("tr_open","tr",1)).map=[n,n+1],l=0;l=4)break;for((p=D2(s)).length&&""===p[0]&&p.shift(),p.length&&""===p[p.length-1]&&p.pop(),c===n+2&&((f=e.push("tbody_open","tbody",1)).map=h=[n+2,0]),(f=e.push("tr_open","tr",1)).map=[c,c+1],l=0;l=4))break;a=++o}return e.line=a,(s=e.push("code_block","code",0)).content=e.getLines(n,a,4+e.blkIndent,!1)+"\n",s.map=[n,e.line],!0}],["fence",function(e,n,r,o){var a,s,i,l,u,c,p,d=!1,f=e.bMarks[n]+e.tShift[n],b=e.eMarks[n];if(e.sCount[n]-e.blkIndent>=4||f+3>b||126!==(a=e.src.charCodeAt(f))&&96!==a||(u=f,(s=(f=e.skipChars(f,a))-u)<3)||(p=e.src.slice(u,f),i=e.src.slice(f,b),96===a&&i.indexOf(String.fromCharCode(a))>=0))return!1;if(o)return!0;for(l=n;!(++l>=r||(f=u=e.bMarks[l]+e.tShift[l],b=e.eMarks[l],f=4||(f=e.skipChars(f,a),f-u=4||62!==e.src.charCodeAt(I))return!1;if(o)return!0;for(b=[],A=[],g=[],E=[],v=e.md.block.ruler.getRules("blockquote"),h=e.parentType,e.parentType="blockquote",d=n;d=(W=e.eMarks[d])));d++)if(62!==e.src.charCodeAt(I++)||R){if(c)break;for(N=!1,i=0,u=v.length;i=W,A.push(e.bsCount[d]),e.bsCount[d]=e.sCount[d]+1+(_?1:0),g.push(e.sCount[d]),e.sCount[d]=f-l,E.push(e.tShift[d]),e.tShift[d]=I-e.bMarks[d]}for(y=e.blkIndent,e.blkIndent=0,(T=e.push("blockquote_open","blockquote",1)).markup=">",T.map=p=[n,0],e.md.block.tokenize(e,n,d),(T=e.push("blockquote_close","blockquote",-1)).markup=">",e.lineMax=H,e.parentType=h,p[1]=e.line,i=0;i=4||42!==(a=e.src.charCodeAt(u++))&&45!==a&&95!==a)return!1;for(s=1;u=4||e.listIndent>=0&&e.sCount[B]-e.listIndent>=4&&e.sCount[B]=e.blkIndent&&(x=!0),(I=N2(e,B))>=0){if(p=!0,le=e.bMarks[B]+e.tShift[B],h=Number(e.src.slice(le,I-1)),x&&1!==h)return!1}else{if(!((I=S2(e,B))>=0))return!1;p=!1}if(x&&e.skipSpaces(I)>=e.eMarks[B])return!1;if(o)return!0;for(y=e.src.charCodeAt(I-1),A=e.tokens.length,p?(V=e.push("ordered_list_open","ol",1),1!==h&&(V.attrs=[["start",h]])):V=e.push("bullet_list_open","ul",1),V.map=b=[B,0],V.markup=String.fromCharCode(y),W=!1,O=e.md.block.ruler.getRules("list"),N=e.parentType,e.parentType="list";B=g?1:E-c)>4&&(u=1),l=c+u,(V=e.push("list_item_open","li",1)).markup=String.fromCharCode(y),V.map=d=[B,0],p&&(V.info=e.src.slice(le,I-1)),R=e.tight,T=e.tShift[B],v=e.sCount[B],_=e.listIndent,e.listIndent=e.blkIndent,e.blkIndent=l,e.tight=!0,e.tShift[B]=s-e.bMarks[B],e.sCount[B]=E,s>=g&&e.isEmpty(B+1)?e.line=Math.min(e.line+2,r):e.md.block.tokenize(e,B,r,!0),(!e.tight||W)&&(S=!1),W=e.line-B>1&&e.isEmpty(e.line-1),e.blkIndent=e.listIndent,e.listIndent=_,e.tShift[B]=T,e.sCount[B]=v,e.tight=R,(V=e.push("list_item_close","li",-1)).markup=String.fromCharCode(y),B=e.line,d[1]=B,B>=r||e.sCount[B]=4)break;for(K=!1,i=0,f=O.length;i=4||91!==e.src.charCodeAt(v))return!1;for(;++v3||e.sCount[R]<0)){for(g=!1,c=0,p=E.length;c"u"&&(e.env.references={}),typeof e.env.references[d]>"u"&&(e.env.references[d]={title:_,href:u}),e.parentType=b,e.line=n+N+1),!0)}],["html_block",function(e,n,r,o){var a,s,i,l,u=e.bMarks[n]+e.tShift[n],c=e.eMarks[n];if(e.sCount[n]-e.blkIndent>=4||!e.md.options.html||60!==e.src.charCodeAt(u))return!1;for(l=e.src.slice(u,c),a=0;a=4||(35!==(a=e.src.charCodeAt(u))||u>=c))return!1;for(s=1,a=e.src.charCodeAt(++u);35===a&&u6||uu&&x2(e.src.charCodeAt(i-1))&&(c=i),e.line=n+1,(l=e.push("heading_open","h"+String(s),1)).markup="########".slice(0,s),l.map=[n,e.line],(l=e.push("inline","",0)).content=e.src.slice(u,c).trim(),l.map=[n,e.line],l.children=[],(l=e.push("heading_close","h"+String(s),-1)).markup="########".slice(0,s)),!0)},["paragraph","reference","blockquote"]],["lheading",function(e,n,r){var o,a,s,i,l,u,c,p,d,b,f=n+1,A=e.md.block.ruler.getRules("paragraph");if(e.sCount[n]-e.blkIndent>=4)return!1;for(b=e.parentType,e.parentType="paragraph";f3)){if(e.sCount[f]>=e.blkIndent&&((u=e.bMarks[f]+e.tShift[f])<(c=e.eMarks[f])&&((45===(d=e.src.charCodeAt(u))||61===d)&&(u=e.skipChars(u,d),(u=e.skipSpaces(u))>=c)))){p=61===d?1:2;break}if(!(e.sCount[f]<0)){for(a=!1,s=0,i=A.length;s3||e.sCount[c]<0)){for(a=!1,s=0,i=p.length;s=n||t.sCount[l]=c){t.line=n;break}for(a=t.line,o=0;o=t.line)throw new Error("block rule didn't increment state.line");break}if(!r)throw new Error("none of the block rules matched");t.tight=!u,t.isEmpty(t.line-1)&&(u=!0),(l=t.line)?@[]^_`{|}~-".split("").forEach((function(t){Fu[t.charCodeAt(0)]=1}));var Fs={};function O2(t,e){var n,r,o,a,s,i=[],l=e.length;for(n=0;n=0;n--)(95===(r=e[n]).marker||42===r.marker)&&-1!==r.end&&(o=e[r.end],i=n>0&&e[n-1].end===r.end+1&&e[n-1].marker===r.marker&&e[n-1].token===r.token-1&&e[r.end+1].token===o.token+1,s=String.fromCharCode(r.marker),(a=t.tokens[r.token]).type=i?"strong_open":"em_open",a.tag=i?"strong":"em",a.nesting=1,a.markup=i?s+s:s,a.content="",(a=t.tokens[o.token]).type=i?"strong_close":"em_close",a.tag=i?"strong":"em",a.nesting=-1,a.markup=i?s+s:s,a.content="",i&&(t.tokens[e[n-1].token].content="",t.tokens[e[r.end+1].token].content="",n--))}Bs.tokenize=function(e,n){var r,o,s=e.pos,i=e.src.charCodeAt(s);if(n||95!==i&&42!==i)return!1;for(o=e.scanDelims(e.pos,42===i),r=0;r\x00-\x20]*)$/,_y=Os.HTML_TAG_RE;var I2=Jf,Sy=ie.has,Ny=ie.isValidEntityCode,M2=ie.fromCodePoint,Ty=/^&#((?:x[a-f0-9]{1,6}|[0-9]{1,7}));/i,wy=/^&([a-z][a-z0-9]{1,31});/i;function F2(t){var e,n,r,o,a,s,i,l,u={},c=t.length;if(c){var p=0,d=-2,f=[];for(e=0;ea;n-=f[n]+1)if((o=t[n]).marker===r.marker&&o.open&&o.end<0&&(i=!1,(o.close||r.open)&&(o.length+r.length)%3==0&&(o.length%3!=0||r.length%3!=0)&&(i=!0),!i)){l=n>0&&!t[n-1].open?f[n-1]+1:0,f[e]=e-n+l,f[n]=l,r.open=!1,o.end=e,o.close=!1,s=-1,d=-2;break}-1!==s&&(u[r.marker][(r.open?3:0)+(r.length||0)%3]=s)}}}var Uu=Lu,B2=ie.isWhiteSpace,P2=ie.isPunctChar,U2=ie.isMdAsciiPunct;function Ho(t,e,n,r){this.src=t,this.env=n,this.md=e,this.tokens=r,this.tokens_meta=Array(r.length),this.pos=0,this.posMax=this.src.length,this.level=0,this.pending="",this.pendingLevel=0,this.cache={},this.delimiters=[],this._prev_delimiters=[],this.backticks={},this.backticksScanned=!1,this.linkLevel=0}Ho.prototype.pushPending=function(){var t=new Uu("text","",0);return t.content=this.pending,t.level=this.pendingLevel,this.tokens.push(t),this.pending="",t},Ho.prototype.push=function(t,e,n){this.pending&&this.pushPending();var r=new Uu(t,e,n),o=null;return n<0&&(this.level--,this.delimiters=this._prev_delimiters.pop()),r.level=this.level,n>0&&(this.level++,this._prev_delimiters.push(this.delimiters),this.delimiters=[],o={delimiters:this.delimiters}),this.pendingLevel=this.level,this.tokens.push(r),this.tokens_meta.push(o),r},Ho.prototype.scanDelims=function(t,e){var r,o,a,s,i,l,u,c,p,n=t,d=!0,f=!0,b=this.posMax,A=this.src.charCodeAt(t);for(r=t>0?this.src.charCodeAt(t-1):32;n0||(r=e.pos,o=e.posMax,r+3>o)||58!==e.src.charCodeAt(r)||47!==e.src.charCodeAt(r+1)||47!==e.src.charCodeAt(r+2)||(a=e.pending.match(sy),!a)||(s=a[1],i=e.md.linkify.matchAtStart(e.src.slice(r-s.length)),!i)||(l=i.url,l.length<=s.length)||(l=l.replace(/\*+$/,""),u=e.md.normalizeLink(l),!e.md.validateLink(u))||(n||(e.pending=e.pending.slice(0,-s.length),(c=e.push("link_open","a",1)).attrs=[["href",u]],c.markup="linkify",c.info="auto",(c=e.push("text","",0)).content=e.md.normalizeLinkText(l),(c=e.push("link_close","a",-1)).markup="linkify",c.info="auto"),e.pos+=l.length-s.length,0))}],["newline",function(e,n){var r,o,a,s=e.pos;if(10!==e.src.charCodeAt(s))return!1;if(r=e.pending.length-1,o=e.posMax,!n)if(r>=0&&32===e.pending.charCodeAt(r))if(r>=1&&32===e.pending.charCodeAt(r-1)){for(a=r-1;a>=1&&32===e.pending.charCodeAt(a-1);)a--;e.pending=e.pending.slice(0,a),e.push("hardbreak","br",0)}else e.pending=e.pending.slice(0,-1),e.push("softbreak","br",0);else e.push("softbreak","br",0);for(s++;s=u)return!1;if(10===(r=e.src.charCodeAt(l))){for(n||e.push("hardbreak","br",0),l++;l=55296&&r<=56319&&l+1=56320&&o<=57343&&(s+=e.src[l+1],l++)),a="\\"+s,n||(i=e.push("text_special","",0),r<256&&0!==Fu[r]?i.content=s:i.content=a,i.markup=a,i.info="escape"),e.pos=l+1,!0}],["backticks",function(e,n){var r,o,a,s,i,l,u,c,p=e.pos;if(96!==e.src.charCodeAt(p))return!1;for(r=p,p++,o=e.posMax;p=A)return!1;if(y=l,(u=e.md.helpers.parseLinkDestination(e.src,l,e.posMax)).ok){for(d=e.md.normalizeLink(u.str),e.md.validateLink(d)?l=u.pos:d="",y=l;l=A||41!==e.src.charCodeAt(l))&&(h=!0),l++}if(h){if(typeof e.env.references>"u")return!1;if(l=0?a=e.src.slice(y,l++):l=s+1):l=s+1,a||(a=e.src.slice(i,s)),!(c=e.env.references[fy(a)]))return e.pos=b,!1;d=c.href,f=c.title}return n||(e.pos=i,e.posMax=s,e.push("link_open","a",1).attrs=r=[["href",d]],f&&r.push(["title",f]),e.linkLevel++,e.md.inline.tokenize(e),e.linkLevel--,e.push("link_close","a",-1)),e.pos=l,e.posMax=A,!0}],["image",function(e,n){var r,o,a,s,i,l,u,c,p,d,f,b,A,y="",h=e.pos,g=e.posMax;if(33!==e.src.charCodeAt(e.pos)||91!==e.src.charCodeAt(e.pos+1)||(l=e.pos+2,(i=e.md.helpers.parseLinkLabel(e,e.pos+1,!1))<0))return!1;if((u=i+1)=g)return!1;for(A=u,(p=e.md.helpers.parseLinkDestination(e.src,u,e.posMax)).ok&&(y=e.md.normalizeLink(p.str),e.md.validateLink(y)?u=p.pos:y=""),A=u;u=g||41!==e.src.charCodeAt(u))return e.pos=h,!1;u++}else{if(typeof e.env.references>"u")return!1;if(u=0?s=e.src.slice(A,u++):u=i+1):u=i+1,s||(s=e.src.slice(l,i)),!(c=e.env.references[gy(s)]))return e.pos=h,!1;y=c.href,d=c.title}return n||(a=e.src.slice(l,i),e.md.inline.parse(a,e.md,e.env,b=[]),(f=e.push("image","img",0)).attrs=r=[["src",y],["alt",""]],f.children=b,f.content=a,d&&r.push(["title",d])),e.pos=u,e.posMax=g,!0}],["autolink",function(e,n){var r,o,a,s,i,l,u=e.pos;if(60!==e.src.charCodeAt(u))return!1;for(i=e.pos,l=e.posMax;;){if(++u>=l||60===(s=e.src.charCodeAt(u)))return!1;if(62===s)break}return r=e.src.slice(i+1,u),by.test(r)?(o=e.md.normalizeLink(r),!!e.md.validateLink(o)&&(n||((a=e.push("link_open","a",1)).attrs=[["href",o]],a.markup="autolink",a.info="auto",(a=e.push("text","",0)).content=e.md.normalizeLinkText(r),(a=e.push("link_close","a",-1)).markup="autolink",a.info="auto"),e.pos+=r.length+2,!0)):!!Ey.test(r)&&(o=e.md.normalizeLink("mailto:"+r),!!e.md.validateLink(o)&&(n||((a=e.push("link_open","a",1)).attrs=[["href",o]],a.markup="autolink",a.info="auto",(a=e.push("text","",0)).content=e.md.normalizeLinkText(r),(a=e.push("link_close","a",-1)).markup="autolink",a.info="auto"),e.pos+=r.length+2,!0))}],["html_inline",function(e,n){var r,o,a,s,i=e.pos;return!(!e.md.options.html||(a=e.posMax,60!==e.src.charCodeAt(i)||i+2>=a)||(r=e.src.charCodeAt(i+1),33!==r&&63!==r&&47!==r&&!function(t){var e=32|t;return e>=97&&e<=122}(r))||(o=e.src.slice(i).match(_y),!o))&&(n||((s=e.push("html_inline","",0)).content=o[0],function(t){return/^\s]/i.test(t)}(s.content)&&e.linkLevel++,function(t){return/^<\/a\s*>/i.test(t)}(s.content)&&e.linkLevel--),e.pos+=o[0].length,!0)}],["entity",function(e,n){var o,a,s,i=e.pos,l=e.posMax;if(38!==e.src.charCodeAt(i)||i+1>=l)return!1;if(35===e.src.charCodeAt(i+1)){if(a=e.src.slice(i).match(Ty))return n||(o="x"===a[1][0].toLowerCase()?parseInt(a[1].slice(1),16):parseInt(a[1],10),(s=e.push("text_special","",0)).content=Ny(o)?M2(o):M2(65533),s.markup=a[0],s.info="entity"),e.pos+=a[0].length,!0}else if((a=e.src.slice(i).match(wy))&&Sy(I2,a[1]))return n||((s=e.push("text_special","",0)).content=I2[a[1]],s.markup=a[0],s.info="entity"),e.pos+=a[0].length,!0;return!1}]],Hu=[["balance_pairs",function(e){var n,r=e.tokens_meta,o=e.tokens_meta.length;for(F2(e.delimiters),n=0;n0&&o++,"text"===a[n].type&&n+1=t.pos)throw new Error("inline rule didn't increment state.pos");break}}else t.pos=t.posMax;e||t.pos++,i[r]=t.pos}},Vo.prototype.tokenize=function(t){for(var e,n,r,o=this.ruler.getRules(""),a=o.length,s=t.posMax,i=t.md.options.maxNesting;t.pos=t.pos)throw new Error("inline rule didn't increment state.pos");break}if(e){if(t.pos>=s)break}else t.pending+=t.src[t.pos++]}t.pending&&t.pushPending()},Vo.prototype.parse=function(t,e,n,r){var o,a,s,i=new this.State(t,e,n,r);for(this.tokenize(i),s=(a=this.ruler2.getRules("")).length,o=0;o=3&&":"===t[e-3]||e>=3&&"/"===t[e-3]?0:r.match(n.re.no_http)[0].length:0}},"mailto:":{validate:function(t,e,n){var r=t.slice(e);return n.re.mailto||(n.re.mailto=new RegExp("^"+n.re.src_email_name+"@"+n.re.src_host_strict,"i")),n.re.mailto.test(r)?r.match(n.re.mailto)[0].length:0}}},Hy="a[cdefgilmnoqrstuwxz]|b[abdefghijmnorstvwyz]|c[acdfghiklmnoruvwxyz]|d[ejkmoz]|e[cegrstu]|f[ijkmor]|g[abdefghilmnpqrstuwy]|h[kmnrtu]|i[delmnoqrst]|j[emop]|k[eghimnprwyz]|l[abcikrstuvy]|m[acdeghklmnopqrstuvwxyz]|n[acefgilopruz]|om|p[aefghklmnrstwy]|qa|r[eosuw]|s[abcdeghijklmnortuvxyz]|t[cdfghjklmnortvwz]|u[agksyz]|v[aceginu]|w[fs]|y[et]|z[amw]",Vy="biz|com|edu|gov|net|org|pro|web|xxx|aero|asia|coop|info|museum|name|shop|рф".split("|");function Us(t){var e=t.re=(H2||(H2=1,Vu=function(t){var e={};t=t||{},e.src_Any=l2().source,e.src_Cc=c2().source,e.src_Z=f2().source,e.src_P=Su.source,e.src_ZPCc=[e.src_Z,e.src_P,e.src_Cc].join("|"),e.src_ZCc=[e.src_Z,e.src_Cc].join("|");var n="[><|]";return e.src_pseudo_letter="(?:(?![><|]|"+e.src_ZPCc+")"+e.src_Any+")",e.src_ip4="(?:(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)",e.src_auth="(?:(?:(?!"+e.src_ZCc+"|[@/\\[\\]()]).)+@)?",e.src_port="(?::(?:6(?:[0-4]\\d{3}|5(?:[0-4]\\d{2}|5(?:[0-2]\\d|3[0-5])))|[1-5]?\\d{1,4}))?",e.src_host_terminator="(?=$|[><|]|"+e.src_ZPCc+")(?!"+(t["---"]?"-(?!--)|":"-|")+"_|:\\d|\\.-|\\.(?!$|"+e.src_ZPCc+"))",e.src_path="(?:[/?#](?:(?!"+e.src_ZCc+"|"+n+"|[()[\\]{}.,\"'?!\\-;]).|\\[(?:(?!"+e.src_ZCc+"|\\]).)*\\]|\\((?:(?!"+e.src_ZCc+"|[)]).)*\\)|\\{(?:(?!"+e.src_ZCc+'|[}]).)*\\}|\\"(?:(?!'+e.src_ZCc+'|["]).)+\\"|\\\'(?:(?!'+e.src_ZCc+"|[']).)+\\'|\\'(?="+e.src_pseudo_letter+"|[-])|\\.{2,}[a-zA-Z0-9%/&]|\\.(?!"+e.src_ZCc+"|[.]|$)|"+(t["---"]?"\\-(?!--(?:[^-]|$))(?:-*)|":"\\-+|")+",(?!"+e.src_ZCc+"|$)|;(?!"+e.src_ZCc+"|$)|\\!+(?!"+e.src_ZCc+"|[!]|$)|\\?(?!"+e.src_ZCc+"|[?]|$))+|\\/)?",e.src_email_name='[\\-;:&=\\+\\$,\\.a-zA-Z0-9_][\\-;:&=\\+\\$,\\"\\.a-zA-Z0-9_]*',e.src_xn="xn--[a-z0-9\\-]{1,59}",e.src_domain_root="(?:"+e.src_xn+"|"+e.src_pseudo_letter+"{1,63})",e.src_domain="(?:"+e.src_xn+"|(?:"+e.src_pseudo_letter+")|(?:"+e.src_pseudo_letter+"(?:-|"+e.src_pseudo_letter+"){0,61}"+e.src_pseudo_letter+"))",e.src_host="(?:(?:(?:(?:"+e.src_domain+")\\.)*"+e.src_domain+"))",e.tpl_host_fuzzy="(?:"+e.src_ip4+"|(?:(?:(?:"+e.src_domain+")\\.)+(?:%TLDS%)))",e.tpl_host_no_ip_fuzzy="(?:(?:(?:"+e.src_domain+")\\.)+(?:%TLDS%))",e.src_host_strict=e.src_host+e.src_host_terminator,e.tpl_host_fuzzy_strict=e.tpl_host_fuzzy+e.src_host_terminator,e.src_host_port_strict=e.src_host+e.src_port+e.src_host_terminator,e.tpl_host_port_fuzzy_strict=e.tpl_host_fuzzy+e.src_port+e.src_host_terminator,e.tpl_host_port_no_ip_fuzzy_strict=e.tpl_host_no_ip_fuzzy+e.src_port+e.src_host_terminator,e.tpl_host_fuzzy_test="localhost|www\\.|\\.\\d{1,3}\\.|(?:\\.(?:%TLDS%)(?:"+e.src_ZPCc+"|>|$))",e.tpl_email_fuzzy='(^|[><|]|"|\\(|'+e.src_ZCc+")("+e.src_email_name+"@"+e.tpl_host_fuzzy_strict+")",e.tpl_link_fuzzy="(^|(?![.:/\\-_@])(?:[$+<=>^`||]|"+e.src_ZPCc+"))((?![$+<=>^`||])"+e.tpl_host_port_fuzzy_strict+e.src_path+")",e.tpl_link_no_ip_fuzzy="(^|(?![.:/\\-_@])(?:[$+<=>^`||]|"+e.src_ZPCc+"))((?![$+<=>^`||])"+e.tpl_host_port_no_ip_fuzzy_strict+e.src_path+")",e}),Vu)(t.__opts__),n=t.__tlds__.slice();function r(i){return i.replace("%TLDS%",e.src_tlds)}t.onCompile(),t.__tlds_replaced__||n.push(Hy),n.push(e.src_xn),e.src_tlds=n.join("|"),e.email_fuzzy=RegExp(r(e.tpl_email_fuzzy),"i"),e.link_fuzzy=RegExp(r(e.tpl_link_fuzzy),"i"),e.link_no_ip_fuzzy=RegExp(r(e.tpl_link_no_ip_fuzzy),"i"),e.host_fuzzy_test=RegExp(r(e.tpl_host_fuzzy_test),"i");var o=[];function a(i,l){throw new Error('(LinkifyIt) Invalid schema "'+i+'": '+l)}t.__compiled__={},Object.keys(t.__schemas__).forEach((function(i){var l=t.__schemas__[i];if(null!==l){var u={validate:null,link:null};if(t.__compiled__[i]=u,function(t){return"[object Object]"===Ps(t)}(l))return!function(t){return"[object RegExp]"===Ps(t)}(l.validate)?V2(l.validate)?u.validate=l.validate:a(i,l):u.validate=function(t){return function(e,n){var r=e.slice(n);return t.test(r)?r.match(t)[0].length:0}}(l.validate),void(V2(l.normalize)?u.normalize=l.normalize:l.normalize?a(i,l):u.normalize=function(t,e){e.normalize(t)});if(function(t){return"[object String]"===Ps(t)}(l))return void o.push(i);a(i,l)}})),o.forEach((function(i){t.__compiled__[t.__schemas__[i]]&&(t.__compiled__[i].validate=t.__compiled__[t.__schemas__[i]].validate,t.__compiled__[i].normalize=t.__compiled__[t.__schemas__[i]].normalize)})),t.__compiled__[""]={validate:null,normalize:function(t,e){e.normalize(t)}};var s=Object.keys(t.__compiled__).filter((function(i){return i.length>0&&t.__compiled__[i]})).map(Py).join("|");t.re.schema_test=RegExp("(^|(?!_)(?:[><|]|"+e.src_ZPCc+"))("+s+")","i"),t.re.schema_search=RegExp("(^|(?!_)(?:[><|]|"+e.src_ZPCc+"))("+s+")","ig"),t.re.schema_at_start=RegExp("^"+t.re.schema_search.source,"i"),t.re.pretest=RegExp("("+t.re.schema_test.source+")|("+t.re.host_fuzzy_test.source+")|@","i"),function(t){t.__index__=-1,t.__text_cache__=""}(t)}function Gy(t,e){var n=t.__index__,r=t.__last_index__,o=t.__text_cache__.slice(n,r);this.schema=t.__schema__.toLowerCase(),this.index=n+e,this.lastIndex=r+e,this.raw=o,this.text=o,this.url=o}function zu(t,e){var n=new Gy(t,e);return t.__compiled__[n.schema].normalize(n,t),n}function ht(t,e){if(!(this instanceof ht))return new ht(t,e);e||function(t){return Object.keys(t||{}).reduce((function(e,n){return e||$2.hasOwnProperty(n)}),!1)}(t)&&(e=t,t={}),this.__opts__=$u({},$2,e),this.__index__=-1,this.__last_index__=-1,this.__schema__="",this.__text_cache__="",this.__schemas__=$u({},qy,t),this.__compiled__={},this.__tlds__=Vy,this.__tlds_replaced__=!1,this.re={},Us(this)}ht.prototype.add=function(e,n){return this.__schemas__[e]=n,Us(this),this},ht.prototype.set=function(e){return this.__opts__=$u(this.__opts__,e),this},ht.prototype.test=function(e){if(this.__text_cache__=e,this.__index__=-1,!e.length)return!1;var n,r,o,a,s,i,l,u;if(this.re.schema_test.test(e))for((l=this.re.schema_search).lastIndex=0;null!==(n=l.exec(e));)if(a=this.testSchemaAt(e,n[2],l.lastIndex)){this.__schema__=n[2],this.__index__=n.index+n[1].length,this.__last_index__=n.index+n[0].length+a;break}return this.__opts__.fuzzyLink&&this.__compiled__["http:"]&&((u=e.search(this.re.host_fuzzy_test))>=0&&(this.__index__<0||u=0&&null!==(o=e.match(this.re.email_fuzzy))&&(s=o.index+o[1].length,i=o.index+o[0].length,(this.__index__<0||sthis.__last_index__)&&(this.__schema__="mailto:",this.__index__=s,this.__last_index__=i))),this.__index__>=0},ht.prototype.pretest=function(e){return this.re.pretest.test(e)},ht.prototype.testSchemaAt=function(e,n,r){return this.__compiled__[n.toLowerCase()]?this.__compiled__[n.toLowerCase()].validate(e,r,this):0},ht.prototype.match=function(e){var n=0,r=[];this.__index__>=0&&this.__text_cache__===e&&(r.push(zu(this,n)),n=this.__last_index__);for(var o=n?e.slice(n):e;this.test(o);)r.push(zu(this,n)),o=o.slice(this.__last_index__),n+=this.__last_index__;return r.length?r:null},ht.prototype.matchAtStart=function(e){if(this.__text_cache__=e,this.__index__=-1,!e.length)return null;var n=this.re.schema_at_start.exec(e);if(!n)return null;var r=this.testSchemaAt(e,n[2],n[0].length);return r?(this.__schema__=n[2],this.__index__=n.index+n[1].length,this.__last_index__=n.index+n[0].length+r,zu(this,0)):null},ht.prototype.tlds=function(e,n){return e=Array.isArray(e)?e:[e],n?(this.__tlds__=this.__tlds__.concat(e).sort().filter((function(r,o,a){return r!==a[o-1]})).reverse(),Us(this),this):(this.__tlds__=e.slice(),this.__tlds_replaced__=!0,Us(this),this)},ht.prototype.normalize=function(e){e.schema||(e.url="http://"+e.url),"mailto:"===e.schema&&!/^mailto:/i.test(e.url)&&(e.url="mailto:"+e.url)},ht.prototype.onCompile=function(){};var Zy=ht;const Pr=2147483647,Ky=/^xn--/,Yy=/[^\0-\x7F]/,Xy=/[\x2E\u3002\uFF0E\uFF61]/g,Qy={overflow:"Overflow: input needs wider integers to process","not-basic":"Illegal input >= 0x80 (not a basic code point)","invalid-input":"Invalid input"},Yt=Math.floor,ju=String.fromCharCode;function On(t){throw new RangeError(Qy[t])}function W2(t,e){const n=t.split("@");let r="";n.length>1&&(r=n[0]+"@",t=n[1]);const a=function(t,e){const n=[];let r=t.length;for(;r--;)n[r]=e(t[r]);return n}((t=t.replace(Xy,".")).split("."),e).join(".");return r+a}function Wu(t){const e=[];let n=0;const r=t.length;for(;n=55296&&o<=56319&&nString.fromCodePoint(...t),eD=function(t){return t>=48&&t<58?t-48+26:t>=65&&t<91?t-65:t>=97&&t<123?t-97:36},Y2=function(t,e){return t+22+75*(t<26)-((0!=e)<<5)},X2=function(t,e,n){let r=0;for(t=n?Yt(t/700):t>>1,t+=Yt(t/e);t>455;r+=36)t=Yt(t/35);return Yt(r+36*t/(t+38))},Ku=function(t){const e=[],n=t.length;let r=0,o=128,a=72,s=t.lastIndexOf("-");s<0&&(s=0);for(let i=0;i=128&&On("not-basic"),e.push(t.charCodeAt(i));for(let i=s>0?s+1:0;i=n&&On("invalid-input");const d=eD(t.charCodeAt(i++));d>=36&&On("invalid-input"),d>Yt((Pr-r)/c)&&On("overflow"),r+=d*c;const f=p<=a?1:p>=a+26?26:p-a;if(dYt(Pr/b)&&On("overflow"),c*=b}const u=e.length+1;a=X2(r-l,u,0==l),Yt(r/u)>Pr-o&&On("overflow"),o+=Yt(r/u),r%=u,e.splice(r++,0,o)}return String.fromCodePoint(...e)},Yu=function(t){const e=[],n=(t=Wu(t)).length;let r=128,o=0,a=72;for(const l of t)l<128&&e.push(ju(l));const s=e.length;let i=s;for(s&&e.push("-");i=r&&cYt((Pr-o)/u)&&On("overflow"),o+=(l-r)*u,r=l;for(const c of t)if(cPr&&On("overflow"),c===r){let p=o;for(let d=36;;d+=36){const f=d<=a?1:d>=a+26?26:d-a;if(p=0))try{e.hostname=em.toASCII(e.hostname)}catch{}return Qn.encode(Qn.format(e))}function hD(t){var e=Qn.parse(t,!0);if(e.hostname&&(!e.protocol||tm.indexOf(e.protocol)>=0))try{e.hostname=em.toUnicode(e.hostname)}catch{}return Qn.decode(Qn.format(e),Qn.decode.defaultChars+"%")}function Tt(t,e){if(!(this instanceof Tt))return new Tt(t,e);e||zo.isString(t)||(e=t||{},t="default"),this.inline=new uD,this.block=new lD,this.core=new iD,this.renderer=new sD,this.linkify=new cD,this.validateLink=mD,this.normalizeLink=gD,this.normalizeLinkText=hD,this.utils=zo,this.helpers=zo.assign({},aD),this.options={},this.configure(t),e&&this.set(e)}Tt.prototype.set=function(t){return zo.assign(this.options,t),this},Tt.prototype.configure=function(t){var n,e=this;if(zo.isString(t)&&!(t=dD[n=t]))throw new Error('Wrong `markdown-it` preset "'+n+'", check name');if(!t)throw new Error("Wrong `markdown-it` preset, can't be empty");return t.options&&e.set(t.options),t.components&&Object.keys(t.components).forEach((function(r){t.components[r].rules&&e[r].ruler.enableOnly(t.components[r].rules),t.components[r].rules2&&e[r].ruler2.enableOnly(t.components[r].rules2)})),this},Tt.prototype.enable=function(t,e){var n=[];Array.isArray(t)||(t=[t]),["core","block","inline"].forEach((function(o){n=n.concat(this[o].ruler.enable(t,!0))}),this),n=n.concat(this.inline.ruler2.enable(t,!0));var r=t.filter((function(o){return n.indexOf(o)<0}));if(r.length&&!e)throw new Error("MarkdownIt. Failed to enable unknown rule(s): "+r);return this},Tt.prototype.disable=function(t,e){var n=[];Array.isArray(t)||(t=[t]),["core","block","inline"].forEach((function(o){n=n.concat(this[o].ruler.disable(t,!0))}),this),n=n.concat(this.inline.ruler2.disable(t,!0));var r=t.filter((function(o){return n.indexOf(o)<0}));if(r.length&&!e)throw new Error("MarkdownIt. Failed to disable unknown rule(s): "+r);return this},Tt.prototype.use=function(t){var e=[this].concat(Array.prototype.slice.call(arguments,1));return t.apply(t,e),this},Tt.prototype.parse=function(t,e){if("string"!=typeof t)throw new Error("Input data should be a String");var n=new this.core.State(t,this,e);return this.core.process(n),n.tokens},Tt.prototype.render=function(t,e){return e=e||{},this.renderer.render(this.parse(t,e),this.options,e)},Tt.prototype.parseInline=function(t,e){var n=new this.core.State(t,this,e);return n.inlineMode=!0,this.core.process(n),n.tokens},Tt.prototype.renderInline=function(t,e){return e=e||{},this.renderer.render(this.parseInline(t,e),this.options,e)};const AD=Ht(Tt);function nm(t){return t instanceof Map?t.clear=t.delete=t.set=function(){throw new Error("map is read-only")}:t instanceof Set&&(t.add=t.clear=t.delete=function(){throw new Error("set is read-only")}),Object.freeze(t),Object.getOwnPropertyNames(t).forEach((e=>{const n=t[e],r=typeof n;("object"===r||"function"===r)&&!Object.isFrozen(n)&&nm(n)})),t}class rm{constructor(e){void 0===e.data&&(e.data={}),this.data=e.data,this.isMatchIgnored=!1}ignoreMatch(){this.isMatchIgnored=!0}}function om(t){return t.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")}function kn(t,...e){const n=Object.create(null);for(const r in t)n[r]=t[r];return e.forEach((function(r){for(const o in r)n[o]=r[o]})),n}const am=t=>!!t.scope;class yD{constructor(e,n){this.buffer="",this.classPrefix=n.classPrefix,e.walk(this)}addText(e){this.buffer+=om(e)}openNode(e){if(!am(e))return;const n=((t,{prefix:e})=>{if(t.startsWith("language:"))return t.replace("language:","language-");if(t.includes(".")){const n=t.split(".");return[`${e}${n.shift()}`,...n.map(((r,o)=>`${r}${"_".repeat(o+1)}`))].join(" ")}return`${e}${t}`})(e.scope,{prefix:this.classPrefix});this.span(n)}closeNode(e){am(e)&&(this.buffer+="")}value(){return this.buffer}span(e){this.buffer+=``}}const sm=(t={})=>{const e={children:[]};return Object.assign(e,t),e};class Xu{constructor(){this.rootNode=sm(),this.stack=[this.rootNode]}get top(){return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(e){this.top.children.push(e)}openNode(e){const n=sm({scope:e});this.add(n),this.stack.push(n)}closeNode(){if(this.stack.length>1)return this.stack.pop()}closeAllNodes(){for(;this.closeNode(););}toJSON(){return JSON.stringify(this.rootNode,null,4)}walk(e){return this.constructor._walk(e,this.rootNode)}static _walk(e,n){return"string"==typeof n?e.addText(n):n.children&&(e.openNode(n),n.children.forEach((r=>this._walk(e,r))),e.closeNode(n)),e}static _collapse(e){"string"!=typeof e&&e.children&&(e.children.every((n=>"string"==typeof n))?e.children=[e.children.join("")]:e.children.forEach((n=>{Xu._collapse(n)})))}}class DD extends Xu{constructor(e){super(),this.options=e}addText(e){""!==e&&this.add(e)}startScope(e){this.openNode(e)}endScope(){this.closeNode()}__addSublanguage(e,n){const r=e.root;n&&(r.scope=`language:${n}`),this.add(r)}toHTML(){return new yD(this,this.options).value()}finalize(){return this.closeAllNodes(),!0}}function Go(t){return t?"string"==typeof t?t:t.source:null}function im(t){return Jn("(?=",t,")")}function CD(t){return Jn("(?:",t,")*")}function SD(t){return Jn("(?:",t,")?")}function Jn(...t){return t.map((n=>Go(n))).join("")}function Qu(...t){return"("+(function(t){const e=t[t.length-1];return"object"==typeof e&&e.constructor===Object?(t.splice(t.length-1,1),e):{}}(t).capture?"":"?:")+t.map((r=>Go(r))).join("|")+")"}function lm(t){return new RegExp(t.toString()+"|").exec("").length-1}const wD=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./;function Ju(t,{joinWith:e}){let n=0;return t.map((r=>{n+=1;const o=n;let a=Go(r),s="";for(;a.length>0;){const i=wD.exec(a);if(!i){s+=a;break}s+=a.substring(0,i.index),a=a.substring(i.index+i[0].length),"\\"===i[0][0]&&i[1]?s+="\\"+String(Number(i[1])+o):(s+=i[0],"("===i[0]&&n++)}return s})).map((r=>`(${r})`)).join(e)}const um="[a-zA-Z]\\w*",ec="[a-zA-Z_]\\w*",cm="\\b\\d+(\\.\\d+)?",dm="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",pm="\\b(0b[01]+)",Zo={begin:"\\\\[\\s\\S]",relevance:0},OD={scope:"string",begin:"'",end:"'",illegal:"\\n",contains:[Zo]},kD={scope:"string",begin:'"',end:'"',illegal:"\\n",contains:[Zo]},qs=function(t,e,n={}){const r=kn({scope:"comment",begin:t,end:e,contains:[]},n);r.contains.push({scope:"doctag",begin:"[ ]*(?=(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):)",end:/(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):/,excludeBegin:!0,relevance:0});const o=Qu("I","a","is","so","us","to","at","if","in","it","on",/[A-Za-z]+['](d|ve|re|ll|t|s|n)/,/[A-Za-z]+[-][a-z]+/,/[A-Za-z][a-z]{2,}/);return r.contains.push({begin:Jn(/[ ]+/,"(",o,/[.]?[:]?([.][ ]|[ ])/,"){3}")}),r},MD=qs("//","$"),FD=qs("/\\*","\\*/"),BD=qs("#","$"),PD={scope:"number",begin:cm,relevance:0},UD={scope:"number",begin:dm,relevance:0},qD={scope:"number",begin:pm,relevance:0},HD={scope:"regexp",begin:/\/(?=[^/\n]*\/)/,end:/\/[gimuy]*/,contains:[Zo,{begin:/\[/,end:/\]/,relevance:0,contains:[Zo]}]},VD={scope:"title",begin:um,relevance:0},$D={scope:"title",begin:ec,relevance:0},zD={begin:"\\.\\s*"+ec,relevance:0};var Hs=Object.freeze({__proto__:null,APOS_STRING_MODE:OD,BACKSLASH_ESCAPE:Zo,BINARY_NUMBER_MODE:qD,BINARY_NUMBER_RE:pm,COMMENT:qs,C_BLOCK_COMMENT_MODE:FD,C_LINE_COMMENT_MODE:MD,C_NUMBER_MODE:UD,C_NUMBER_RE:dm,END_SAME_AS_BEGIN:function(t){return Object.assign(t,{"on:begin":(e,n)=>{n.data._beginMatch=e[1]},"on:end":(e,n)=>{n.data._beginMatch!==e[1]&&n.ignoreMatch()}})},HASH_COMMENT_MODE:BD,IDENT_RE:um,MATCH_NOTHING_RE:/\b\B/,METHOD_GUARD:zD,NUMBER_MODE:PD,NUMBER_RE:cm,PHRASAL_WORDS_MODE:{begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},QUOTE_STRING_MODE:kD,REGEXP_MODE:HD,RE_STARTERS_RE:"!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",SHEBANG:(t={})=>{const e=/^#![ ]*\//;return t.binary&&(t.begin=Jn(e,/.*\b/,t.binary,/\b.*/)),kn({scope:"meta",begin:e,end:/$/,relevance:0,"on:begin":(n,r)=>{0!==n.index&&r.ignoreMatch()}},t)},TITLE_MODE:VD,UNDERSCORE_IDENT_RE:ec,UNDERSCORE_TITLE_MODE:$D});function GD(t,e){"."===t.input[t.index-1]&&e.ignoreMatch()}function ZD(t,e){void 0!==t.className&&(t.scope=t.className,delete t.className)}function jD(t,e){e&&t.beginKeywords&&(t.begin="\\b("+t.beginKeywords.split(" ").join("|")+")(?!\\.)(?=\\b|\\s)",t.__beforeBegin=GD,t.keywords=t.keywords||t.beginKeywords,delete t.beginKeywords,void 0===t.relevance&&(t.relevance=0))}function WD(t,e){Array.isArray(t.illegal)&&(t.illegal=Qu(...t.illegal))}function KD(t,e){if(t.match){if(t.begin||t.end)throw new Error("begin & end are not supported with match");t.begin=t.match,delete t.match}}function YD(t,e){void 0===t.relevance&&(t.relevance=1)}const XD=(t,e)=>{if(!t.beforeMatch)return;if(t.starts)throw new Error("beforeMatch cannot be used with starts");const n=Object.assign({},t);Object.keys(t).forEach((r=>{delete t[r]})),t.keywords=n.keywords,t.begin=Jn(n.beforeMatch,im(n.begin)),t.starts={relevance:0,contains:[Object.assign(n,{endsParent:!0})]},t.relevance=0,delete n.beforeMatch},QD=["of","and","for","in","not","or","if","then","parent","list","value"],JD="keyword";function fm(t,e,n=JD){const r=Object.create(null);return"string"==typeof t?o(n,t.split(" ")):Array.isArray(t)?o(n,t):Object.keys(t).forEach((function(a){Object.assign(r,fm(t[a],e,a))})),r;function o(a,s){e&&(s=s.map((i=>i.toLowerCase()))),s.forEach((function(i){const l=i.split("|");r[l[0]]=[a,e3(l[0],l[1])]}))}}function e3(t,e){return e?Number(e):function(t){return QD.includes(t.toLowerCase())}(t)?0:1}const mm={},er=t=>{console.error(t)},gm=(t,...e)=>{console.log(`WARN: ${t}`,...e)},Ur=(t,e)=>{mm[`${t}/${e}`]||(console.log(`Deprecated as of ${t}. ${e}`),mm[`${t}/${e}`]=!0)},Vs=new Error;function hm(t,e,{key:n}){let r=0;const o=t[n],a={},s={};for(let i=1;i<=e.length;i++)s[i+r]=o[i],a[i+r]=!0,r+=lm(e[i-1]);t[n]=s,t[n]._emit=a,t[n]._multi=!0}function a3(t){(function(t){t.scope&&"object"==typeof t.scope&&null!==t.scope&&(t.beginScope=t.scope,delete t.scope)})(t),"string"==typeof t.beginScope&&(t.beginScope={_wrap:t.beginScope}),"string"==typeof t.endScope&&(t.endScope={_wrap:t.endScope}),function(t){if(Array.isArray(t.begin)){if(t.skip||t.excludeBegin||t.returnBegin)throw er("skip, excludeBegin, returnBegin not compatible with beginScope: {}"),Vs;if("object"!=typeof t.beginScope||null===t.beginScope)throw er("beginScope must be object"),Vs;hm(t,t.begin,{key:"beginScope"}),t.begin=Ju(t.begin,{joinWith:""})}}(t),function(t){if(Array.isArray(t.end)){if(t.skip||t.excludeEnd||t.returnEnd)throw er("skip, excludeEnd, returnEnd not compatible with endScope: {}"),Vs;if("object"!=typeof t.endScope||null===t.endScope)throw er("endScope must be object"),Vs;hm(t,t.end,{key:"endScope"}),t.end=Ju(t.end,{joinWith:""})}}(t)}function s3(t){function e(s,i){return new RegExp(Go(s),"m"+(t.case_insensitive?"i":"")+(t.unicodeRegex?"u":"")+(i?"g":""))}class n{constructor(){this.matchIndexes={},this.regexes=[],this.matchAt=1,this.position=0}addRule(i,l){l.position=this.position++,this.matchIndexes[this.matchAt]=l,this.regexes.push([l,i]),this.matchAt+=lm(i)+1}compile(){0===this.regexes.length&&(this.exec=()=>null);const i=this.regexes.map((l=>l[1]));this.matcherRe=e(Ju(i,{joinWith:"|"}),!0),this.lastIndex=0}exec(i){this.matcherRe.lastIndex=this.lastIndex;const l=this.matcherRe.exec(i);if(!l)return null;const u=l.findIndex(((p,d)=>d>0&&void 0!==p)),c=this.matchIndexes[u];return l.splice(0,u),Object.assign(l,c)}}class r{constructor(){this.rules=[],this.multiRegexes=[],this.count=0,this.lastIndex=0,this.regexIndex=0}getMatcher(i){if(this.multiRegexes[i])return this.multiRegexes[i];const l=new n;return this.rules.slice(i).forEach((([u,c])=>l.addRule(u,c))),l.compile(),this.multiRegexes[i]=l,l}resumingScanAtSamePosition(){return 0!==this.regexIndex}considerAll(){this.regexIndex=0}addRule(i,l){this.rules.push([i,l]),"begin"===l.type&&this.count++}exec(i){const l=this.getMatcher(this.regexIndex);l.lastIndex=this.lastIndex;let u=l.exec(i);if(this.resumingScanAtSamePosition()&&(!u||u.index!==this.lastIndex)){const c=this.getMatcher(0);c.lastIndex=this.lastIndex+1,u=c.exec(i)}return u&&(this.regexIndex+=u.position+1,this.regexIndex===this.count&&this.considerAll()),u}}if(t.compilerExtensions||(t.compilerExtensions=[]),t.contains&&t.contains.includes("self"))throw new Error("ERR: contains `self` is not supported at the top-level of a language. See documentation.");return t.classNameAliases=kn(t.classNameAliases||{}),function a(s,i){const l=s;if(s.isCompiled)return l;[ZD,KD,a3,XD].forEach((c=>c(s,i))),t.compilerExtensions.forEach((c=>c(s,i))),s.__beforeBegin=null,[jD,WD,YD].forEach((c=>c(s,i))),s.isCompiled=!0;let u=null;return"object"==typeof s.keywords&&s.keywords.$pattern&&(s.keywords=Object.assign({},s.keywords),u=s.keywords.$pattern,delete s.keywords.$pattern),u=u||/\w+/,s.keywords&&(s.keywords=fm(s.keywords,t.case_insensitive)),l.keywordPatternRe=e(u,!0),i&&(s.begin||(s.begin=/\B|\b/),l.beginRe=e(l.begin),!s.end&&!s.endsWithParent&&(s.end=/\B|\b/),s.end&&(l.endRe=e(l.end)),l.terminatorEnd=Go(l.end)||"",s.endsWithParent&&i.terminatorEnd&&(l.terminatorEnd+=(s.end?"|":"")+i.terminatorEnd)),s.illegal&&(l.illegalRe=e(s.illegal)),s.contains||(s.contains=[]),s.contains=[].concat(...s.contains.map((function(c){return function(t){return t.variants&&!t.cachedVariants&&(t.cachedVariants=t.variants.map((function(e){return kn(t,{variants:null},e)}))),t.cachedVariants?t.cachedVariants:Em(t)?kn(t,{starts:t.starts?kn(t.starts):null}):Object.isFrozen(t)?kn(t):t}("self"===c?s:c)}))),s.contains.forEach((function(c){a(c,l)})),s.starts&&a(s.starts,i),l.matcher=function(s){const i=new r;return s.contains.forEach((l=>i.addRule(l.begin,{rule:l,type:"begin"}))),s.terminatorEnd&&i.addRule(s.terminatorEnd,{type:"end"}),s.illegal&&i.addRule(s.illegal,{type:"illegal"}),i}(l),l}(t)}function Em(t){return!!t&&(t.endsWithParent||Em(t.starts))}class u3 extends Error{constructor(e,n){super(e),this.name="HTMLInjectionError",this.html=n}}const tc=om,bm=kn,Am=Symbol("nomatch"),_m=function(t){const e=Object.create(null),n=Object.create(null),r=[];let o=!0;const a="Could not find the language '{}', did you forget to load/include a language module?",s={disableAutodetect:!0,name:"Plain text",contains:[]};let i={ignoreUnescapedHTML:!1,throwUnescapedHTML:!1,noHighlightRe:/^(no-?highlight)$/i,languageDetectRe:/\blang(?:uage)?-([\w-]+)\b/i,classPrefix:"hljs-",cssSelector:"pre code",languages:null,__emitter:DD};function l(x){return i.noHighlightRe.test(x)}function c(x,S,C){let L="",k="";"object"==typeof S?(L=x,C=S.ignoreIllegals,k=S.language):(Ur("10.7.0","highlight(lang, code, ...args) has been deprecated."),Ur("10.7.0","Please use highlight(code, options) instead.\nhttps://github.com/highlightjs/highlight.js/issues/2277"),k=x,L=S),void 0===C&&(C=!0);const $={code:L,language:k};V("before:highlight",$);const j=$.result?$.result:p($.language,$.code,C);return j.code=$.code,V("after:highlight",j),j}function p(x,S,C,L){const k=Object.create(null);function $(P,z){return P.keywords[z]}function j(){if(!X.keywords)return void Ce.addText(se);let P=0;X.keywordPatternRe.lastIndex=0;let z=X.keywordPatternRe.exec(se),Q="";for(;z;){Q+=se.substring(P,z.index);const re=Ne.case_insensitive?z[0].toLowerCase():z[0],he=$(X,re);if(he){const[We,na]=he;if(Ce.addText(Q),Q="",k[re]=(k[re]||0)+1,k[re]<=7&&(qt+=na),We.startsWith("_"))Q+=z[0];else{const ra=Ne.classNameAliases[We]||We;ue(z[0],ra)}}else Q+=z[0];P=X.keywordPatternRe.lastIndex,z=X.keywordPatternRe.exec(se)}Q+=se.substring(P),Ce.addText(Q)}function pe(){null!=X.subLanguage?function(){if(""===se)return;let P=null;if("string"==typeof X.subLanguage){if(!e[X.subLanguage])return void Ce.addText(se);P=p(X.subLanguage,se,!0,Zr[X.subLanguage]),Zr[X.subLanguage]=P._top}else P=f(se,X.subLanguage.length?X.subLanguage:null);X.relevance>0&&(qt+=P.relevance),Ce.__addSublanguage(P._emitter,P.language)}():j(),se=""}function ue(P,z){""!==P&&(Ce.startScope(z),Ce.addText(P),Ce.endScope())}function ce(P,z){let Q=1;const re=z.length-1;for(;Q<=re;){if(!P._emit[Q]){Q++;continue}const he=Ne.classNameAliases[P[Q]]||P[Q],We=z[Q];he?ue(We,he):(se=We,j(),se=""),Q++}}function bt(P,z){return P.scope&&"string"==typeof P.scope&&Ce.openNode(Ne.classNameAliases[P.scope]||P.scope),P.beginScope&&(P.beginScope._wrap?(ue(se,Ne.classNameAliases[P.beginScope._wrap]||P.beginScope._wrap),se=""):P.beginScope._multi&&(ce(P.beginScope,z),se="")),X=Object.create(P,{parent:{value:X}}),X}function Ut(P,z,Q){let re=function(t,e){const n=t&&t.exec(e);return n&&0===n.index}(P.endRe,Q);if(re){if(P["on:end"]){const he=new rm(P);P["on:end"](z,he),he.isMatchIgnored&&(re=!1)}if(re){for(;P.endsParent&&P.parent;)P=P.parent;return P}}if(P.endsWithParent)return Ut(P.parent,z,Q)}function At(P){return 0===X.matcher.regexIndex?(se+=P[0],1):(Wr=!0,0)}function xt(P){const z=P[0],Q=S.substring(P.index),re=Ut(X,P,Q);if(!re)return Am;const he=X;X.endScope&&X.endScope._wrap?(pe(),ue(z,X.endScope._wrap)):X.endScope&&X.endScope._multi?(pe(),ce(X.endScope,P)):he.skip?se+=z:(he.returnEnd||he.excludeEnd||(se+=z),pe(),he.excludeEnd&&(se=z));do{X.scope&&Ce.closeNode(),!X.skip&&!X.subLanguage&&(qt+=X.relevance),X=X.parent}while(X!==re.parent);return re.starts&&bt(re.starts,P),he.returnEnd?0:z.length}let Oe={};function Be(P,z){const Q=z&&z[0];if(se+=P,null==Q)return pe(),0;if("begin"===Oe.type&&"end"===z.type&&Oe.index===z.index&&""===Q){if(se+=S.slice(z.index,z.index+1),!o){const re=new Error(`0 width match regex (${x})`);throw re.languageName=x,re.badRule=Oe.rule,re}return 1}if(Oe=z,"begin"===z.type)return function(P){const z=P[0],Q=P.rule,re=new rm(Q),he=[Q.__beforeBegin,Q["on:begin"]];for(const We of he)if(We&&(We(P,re),re.isMatchIgnored))return At(z);return Q.skip?se+=z:(Q.excludeBegin&&(se+=z),pe(),!Q.returnBegin&&!Q.excludeBegin&&(se=z)),bt(Q,P),Q.returnBegin?0:z.length}(z);if("illegal"===z.type&&!C){const re=new Error('Illegal lexeme "'+Q+'" for mode "'+(X.scope||"")+'"');throw re.mode=X,re}if("end"===z.type){const re=xt(z);if(re!==Am)return re}if("illegal"===z.type&&""===Q)return 1;if(jr>1e5&&jr>3*z.index)throw new Error("potential infinite loop, way more iterations than matches");return se+=Q,Q.length}const Ne=H(x);if(!Ne)throw er(a.replace("{}",x)),new Error('Unknown language: "'+x+'"');const si=s3(Ne);let Gr="",X=L||si;const Zr={},Ce=new i.__emitter(i);!function(){const P=[];for(let z=X;z!==Ne;z=z.parent)z.scope&&P.unshift(z.scope);P.forEach((z=>Ce.openNode(z)))}();let se="",qt=0,Qt=0,jr=0,Wr=!1;try{if(Ne.__emitTokens)Ne.__emitTokens(S,Ce);else{for(X.matcher.considerAll();;){jr++,Wr?Wr=!1:X.matcher.considerAll(),X.matcher.lastIndex=Qt;const P=X.matcher.exec(S);if(!P)break;const Q=Be(S.substring(Qt,P.index),P);Qt=P.index+Q}Be(S.substring(Qt))}return Ce.finalize(),Gr=Ce.toHTML(),{language:x,value:Gr,relevance:qt,illegal:!1,_emitter:Ce,_top:X}}catch(P){if(P.message&&P.message.includes("Illegal"))return{language:x,value:tc(S),illegal:!0,relevance:0,_illegalBy:{message:P.message,index:Qt,context:S.slice(Qt-100,Qt+100),mode:P.mode,resultSoFar:Gr},_emitter:Ce};if(o)return{language:x,value:tc(S),illegal:!1,relevance:0,errorRaised:P,_emitter:Ce,_top:X};throw P}}function f(x,S){S=S||i.languages||Object.keys(e);const C=function(x){const S={value:tc(x),illegal:!1,relevance:0,_top:s,_emitter:new i.__emitter(i)};return S._emitter.addText(x),S}(x),L=S.filter(H).filter(W).map((pe=>p(pe,x,!1)));L.unshift(C);const k=L.sort(((pe,ue)=>{if(pe.relevance!==ue.relevance)return ue.relevance-pe.relevance;if(pe.language&&ue.language){if(H(pe.language).supersetOf===ue.language)return 1;if(H(ue.language).supersetOf===pe.language)return-1}return 0})),[$,j]=k,ge=$;return ge.secondBest=j,ge}function A(x){let S=null;const C=function(x){let S=x.className+" ";S+=x.parentNode?x.parentNode.className:"";const C=i.languageDetectRe.exec(S);if(C){const L=H(C[1]);return L||(gm(a.replace("{}",C[1])),gm("Falling back to no-highlight mode for this block.",x)),L?C[1]:"no-highlight"}return S.split(/\s+/).find((L=>l(L)||H(L)))}(x);if(l(C))return;if(V("before:highlightElement",{el:x,language:C}),x.dataset.highlighted)return void console.log("Element previously highlighted. To highlight again, first unset `dataset.highlighted`.",x);if(x.children.length>0&&(i.ignoreUnescapedHTML||(console.warn("One of your code blocks includes unescaped HTML. This is a potentially serious security risk."),console.warn("https://github.com/highlightjs/highlight.js/wiki/security"),console.warn("The element with unescaped HTML:"),console.warn(x)),i.throwUnescapedHTML))throw new u3("One of your code blocks includes unescaped HTML.",x.innerHTML);S=x;const L=S.textContent,k=C?c(L,{language:C,ignoreIllegals:!0}):f(L);x.innerHTML=k.value,x.dataset.highlighted="yes",function(x,S,C){const L=S&&n[S]||C;x.classList.add("hljs"),x.classList.add(`language-${L}`)}(x,C,k.language),x.result={language:k.language,re:k.relevance,relevance:k.relevance},k.secondBest&&(x.secondBest={language:k.secondBest.language,relevance:k.secondBest.relevance}),V("after:highlightElement",{el:x,result:k,text:L})}let E=!1;function _(){"loading"!==document.readyState?document.querySelectorAll(i.cssSelector).forEach(A):E=!0}function H(x){return x=(x||"").toLowerCase(),e[x]||e[n[x]]}function I(x,{languageName:S}){"string"==typeof x&&(x=[x]),x.forEach((C=>{n[C.toLowerCase()]=S}))}function W(x){const S=H(x);return S&&!S.disableAutodetect}function V(x,S){const C=x;r.forEach((function(L){L[C]&&L[C](S)}))}typeof window<"u"&&window.addEventListener&&window.addEventListener("DOMContentLoaded",(function(){E&&_()}),!1),Object.assign(t,{highlight:c,highlightAuto:f,highlightAll:_,highlightElement:A,highlightBlock:function(x){return Ur("10.7.0","highlightBlock will be removed entirely in v12.0"),Ur("10.7.0","Please use highlightElement now."),A(x)},configure:function(x){i=bm(i,x)},initHighlighting:()=>{_(),Ur("10.6.0","initHighlighting() deprecated. Use highlightAll() now.")},initHighlightingOnLoad:function(){_(),Ur("10.6.0","initHighlightingOnLoad() deprecated. Use highlightAll() now.")},registerLanguage:function(x,S){let C=null;try{C=S(t)}catch(L){if(er("Language definition for '{}' could not be registered.".replace("{}",x)),!o)throw L;er(L),C=s}C.name||(C.name=x),e[x]=C,C.rawDefinition=S.bind(null,t),C.aliases&&I(C.aliases,{languageName:x})},unregisterLanguage:function(x){delete e[x];for(const S of Object.keys(n))n[S]===x&&delete n[S]},listLanguages:function(){return Object.keys(e)},getLanguage:H,registerAliases:I,autoDetection:W,inherit:bm,addPlugin:function(x){(function(x){x["before:highlightBlock"]&&!x["before:highlightElement"]&&(x["before:highlightElement"]=S=>{x["before:highlightBlock"](Object.assign({block:S.el},S))}),x["after:highlightBlock"]&&!x["after:highlightElement"]&&(x["after:highlightElement"]=S=>{x["after:highlightBlock"](Object.assign({block:S.el},S))})})(x),r.push(x)},removePlugin:function(x){const S=r.indexOf(x);-1!==S&&r.splice(S,1)}}),t.debugMode=function(){o=!1},t.safeMode=function(){o=!0},t.versionString="11.9.0",t.regex={concat:Jn,lookahead:im,either:Qu,optional:SD,anyNumberOfTimes:CD};for(const x in Hs)"object"==typeof Hs[x]&&nm(Hs[x]);return Object.assign(t,Hs),t},qr=_m({});qr.newInstance=()=>_m({});var d3=qr;qr.HighlightJS=qr,qr.default=qr;const J=Ht(d3);const b3=["a","abbr","address","article","aside","audio","b","blockquote","body","button","canvas","caption","cite","code","dd","del","details","dfn","div","dl","dt","em","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","header","hgroup","html","i","iframe","img","input","ins","kbd","label","legend","li","main","mark","menu","nav","object","ol","p","q","quote","samp","section","span","strong","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","tr","ul","var","video"],A3=["any-hover","any-pointer","aspect-ratio","color","color-gamut","color-index","device-aspect-ratio","device-height","device-width","display-mode","forced-colors","grid","height","hover","inverted-colors","monochrome","orientation","overflow-block","overflow-inline","pointer","prefers-color-scheme","prefers-contrast","prefers-reduced-motion","prefers-reduced-transparency","resolution","scan","scripting","update","width","min-width","max-width","min-height","max-height"],_3=["active","any-link","blank","checked","current","default","defined","dir","disabled","drop","empty","enabled","first","first-child","first-of-type","fullscreen","future","focus","focus-visible","focus-within","has","host","host-context","hover","indeterminate","in-range","invalid","is","lang","last-child","last-of-type","left","link","local-link","not","nth-child","nth-col","nth-last-child","nth-last-col","nth-last-of-type","nth-of-type","only-child","only-of-type","optional","out-of-range","past","placeholder-shown","read-only","read-write","required","right","root","scope","target","target-within","user-invalid","valid","visited","where"],v3=["after","backdrop","before","cue","cue-region","first-letter","first-line","grammar-error","marker","part","placeholder","selection","slotted","spelling-error"],y3=["align-content","align-items","align-self","all","animation","animation-delay","animation-direction","animation-duration","animation-fill-mode","animation-iteration-count","animation-name","animation-play-state","animation-timing-function","backface-visibility","background","background-attachment","background-blend-mode","background-clip","background-color","background-image","background-origin","background-position","background-repeat","background-size","block-size","border","border-block","border-block-color","border-block-end","border-block-end-color","border-block-end-style","border-block-end-width","border-block-start","border-block-start-color","border-block-start-style","border-block-start-width","border-block-style","border-block-width","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius","border-bottom-style","border-bottom-width","border-collapse","border-color","border-image","border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width","border-inline","border-inline-color","border-inline-end","border-inline-end-color","border-inline-end-style","border-inline-end-width","border-inline-start","border-inline-start-color","border-inline-start-style","border-inline-start-width","border-inline-style","border-inline-width","border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right","border-right-color","border-right-style","border-right-width","border-spacing","border-style","border-top","border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width","border-width","bottom","box-decoration-break","box-shadow","box-sizing","break-after","break-before","break-inside","caption-side","caret-color","clear","clip","clip-path","clip-rule","color","column-count","column-fill","column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width","columns","contain","content","content-visibility","counter-increment","counter-reset","cue","cue-after","cue-before","cursor","direction","display","empty-cells","filter","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","float","flow","font","font-display","font-family","font-feature-settings","font-kerning","font-language-override","font-size","font-size-adjust","font-smoothing","font-stretch","font-style","font-synthesis","font-variant","font-variant-caps","font-variant-east-asian","font-variant-ligatures","font-variant-numeric","font-variant-position","font-variation-settings","font-weight","gap","glyph-orientation-vertical","grid","grid-area","grid-auto-columns","grid-auto-flow","grid-auto-rows","grid-column","grid-column-end","grid-column-start","grid-gap","grid-row","grid-row-end","grid-row-start","grid-template","grid-template-areas","grid-template-columns","grid-template-rows","hanging-punctuation","height","hyphens","icon","image-orientation","image-rendering","image-resolution","ime-mode","inline-size","isolation","justify-content","left","letter-spacing","line-break","line-height","list-style","list-style-image","list-style-position","list-style-type","margin","margin-block","margin-block-end","margin-block-start","margin-bottom","margin-inline","margin-inline-end","margin-inline-start","margin-left","margin-right","margin-top","marks","mask","mask-border","mask-border-mode","mask-border-outset","mask-border-repeat","mask-border-slice","mask-border-source","mask-border-width","mask-clip","mask-composite","mask-image","mask-mode","mask-origin","mask-position","mask-repeat","mask-size","mask-type","max-block-size","max-height","max-inline-size","max-width","min-block-size","min-height","min-inline-size","min-width","mix-blend-mode","nav-down","nav-index","nav-left","nav-right","nav-up","none","normal","object-fit","object-position","opacity","order","orphans","outline","outline-color","outline-offset","outline-style","outline-width","overflow","overflow-wrap","overflow-x","overflow-y","padding","padding-block","padding-block-end","padding-block-start","padding-bottom","padding-inline","padding-inline-end","padding-inline-start","padding-left","padding-right","padding-top","page-break-after","page-break-before","page-break-inside","pause","pause-after","pause-before","perspective","perspective-origin","pointer-events","position","quotes","resize","rest","rest-after","rest-before","right","row-gap","scroll-margin","scroll-margin-block","scroll-margin-block-end","scroll-margin-block-start","scroll-margin-bottom","scroll-margin-inline","scroll-margin-inline-end","scroll-margin-inline-start","scroll-margin-left","scroll-margin-right","scroll-margin-top","scroll-padding","scroll-padding-block","scroll-padding-block-end","scroll-padding-block-start","scroll-padding-bottom","scroll-padding-inline","scroll-padding-inline-end","scroll-padding-inline-start","scroll-padding-left","scroll-padding-right","scroll-padding-top","scroll-snap-align","scroll-snap-stop","scroll-snap-type","scrollbar-color","scrollbar-gutter","scrollbar-width","shape-image-threshold","shape-margin","shape-outside","speak","speak-as","src","tab-size","table-layout","text-align","text-align-all","text-align-last","text-combine-upright","text-decoration","text-decoration-color","text-decoration-line","text-decoration-style","text-emphasis","text-emphasis-color","text-emphasis-position","text-emphasis-style","text-indent","text-justify","text-orientation","text-overflow","text-rendering","text-shadow","text-transform","text-underline-position","top","transform","transform-box","transform-origin","transform-style","transition","transition-delay","transition-duration","transition-property","transition-timing-function","unicode-bidi","vertical-align","visibility","voice-balance","voice-duration","voice-family","voice-pitch","voice-range","voice-rate","voice-stress","voice-volume","white-space","widows","width","will-change","word-break","word-spacing","word-wrap","writing-mode","z-index"].reverse();var Hr="[0-9](_*[0-9])*",$s=`\\.(${Hr})`,zs="[0-9a-fA-F](_*[0-9a-fA-F])*",vm={className:"number",variants:[{begin:`(\\b(${Hr})((${$s})|\\.)?|(${$s}))[eE][+-]?(${Hr})[fFdD]?\\b`},{begin:`\\b(${Hr})((${$s})[fFdD]?\\b|\\.([fFdD]\\b)?)`},{begin:`(${$s})[fFdD]?\\b`},{begin:`\\b(${Hr})[fFdD]\\b`},{begin:`\\b0[xX]((${zs})\\.?|(${zs})?\\.(${zs}))[pP][+-]?(${Hr})[fFdD]?\\b`},{begin:"\\b(0|[1-9](_*[0-9])*)[lL]?\\b"},{begin:`\\b0[xX](${zs})[lL]?\\b`},{begin:"\\b0(_*[0-7])*[lL]?\\b"},{begin:"\\b0[bB][01](_*[01])*[lL]?\\b"}],relevance:0};function ym(t,e,n){return-1===n?"":t.replace(e,(r=>ym(t,e,n-1)))}const Dm="[A-Za-z$_][0-9A-Za-z$_]*",x3=["as","in","of","if","for","while","finally","var","new","function","do","return","void","else","break","catch","instanceof","with","throw","case","default","try","switch","continue","typeof","delete","let","yield","const","class","debugger","async","await","static","import","from","export","extends"],R3=["true","false","null","undefined","NaN","Infinity"],Cm=["Object","Function","Boolean","Symbol","Math","Date","Number","BigInt","String","RegExp","Array","Float32Array","Float64Array","Int8Array","Uint8Array","Uint8ClampedArray","Int16Array","Int32Array","Uint16Array","Uint32Array","BigInt64Array","BigUint64Array","Set","Map","WeakSet","WeakMap","ArrayBuffer","SharedArrayBuffer","Atomics","DataView","JSON","Promise","Generator","GeneratorFunction","AsyncFunction","Reflect","Proxy","Intl","WebAssembly"],Sm=["Error","EvalError","InternalError","RangeError","ReferenceError","SyntaxError","TypeError","URIError"],Nm=["setInterval","setTimeout","clearInterval","clearTimeout","require","exports","eval","isFinite","isNaN","parseFloat","parseInt","decodeURI","decodeURIComponent","encodeURI","encodeURIComponent","escape","unescape"],L3=["arguments","this","super","console","window","document","localStorage","sessionStorage","module","global"],O3=[].concat(Nm,Cm,Sm);var Vr="[0-9](_*[0-9])*",Gs=`\\.(${Vr})`,Zs="[0-9a-fA-F](_*[0-9a-fA-F])*",M3={className:"number",variants:[{begin:`(\\b(${Vr})((${Gs})|\\.)?|(${Gs}))[eE][+-]?(${Vr})[fFdD]?\\b`},{begin:`\\b(${Vr})((${Gs})[fFdD]?\\b|\\.([fFdD]\\b)?)`},{begin:`(${Gs})[fFdD]?\\b`},{begin:`\\b(${Vr})[fFdD]\\b`},{begin:`\\b0[xX]((${Zs})\\.?|(${Zs})?\\.(${Zs}))[pP][+-]?(${Vr})[fFdD]?\\b`},{begin:"\\b(0|[1-9](_*[0-9])*)[lL]?\\b"},{begin:`\\b0[xX](${Zs})[lL]?\\b`},{begin:"\\b0(_*[0-7])*[lL]?\\b"},{begin:"\\b0[bB][01](_*[01])*[lL]?\\b"}],relevance:0};const P3=["a","abbr","address","article","aside","audio","b","blockquote","body","button","canvas","caption","cite","code","dd","del","details","dfn","div","dl","dt","em","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","header","hgroup","html","i","iframe","img","input","ins","kbd","label","legend","li","main","mark","menu","nav","object","ol","p","q","quote","samp","section","span","strong","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","tr","ul","var","video"],U3=["any-hover","any-pointer","aspect-ratio","color","color-gamut","color-index","device-aspect-ratio","device-height","device-width","display-mode","forced-colors","grid","height","hover","inverted-colors","monochrome","orientation","overflow-block","overflow-inline","pointer","prefers-color-scheme","prefers-contrast","prefers-reduced-motion","prefers-reduced-transparency","resolution","scan","scripting","update","width","min-width","max-width","min-height","max-height"],Tm=["active","any-link","blank","checked","current","default","defined","dir","disabled","drop","empty","enabled","first","first-child","first-of-type","fullscreen","future","focus","focus-visible","focus-within","has","host","host-context","hover","indeterminate","in-range","invalid","is","lang","last-child","last-of-type","left","link","local-link","not","nth-child","nth-col","nth-last-child","nth-last-col","nth-last-of-type","nth-of-type","only-child","only-of-type","optional","out-of-range","past","placeholder-shown","read-only","read-write","required","right","root","scope","target","target-within","user-invalid","valid","visited","where"],wm=["after","backdrop","before","cue","cue-region","first-letter","first-line","grammar-error","marker","part","placeholder","selection","slotted","spelling-error"],q3=["align-content","align-items","align-self","all","animation","animation-delay","animation-direction","animation-duration","animation-fill-mode","animation-iteration-count","animation-name","animation-play-state","animation-timing-function","backface-visibility","background","background-attachment","background-blend-mode","background-clip","background-color","background-image","background-origin","background-position","background-repeat","background-size","block-size","border","border-block","border-block-color","border-block-end","border-block-end-color","border-block-end-style","border-block-end-width","border-block-start","border-block-start-color","border-block-start-style","border-block-start-width","border-block-style","border-block-width","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius","border-bottom-style","border-bottom-width","border-collapse","border-color","border-image","border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width","border-inline","border-inline-color","border-inline-end","border-inline-end-color","border-inline-end-style","border-inline-end-width","border-inline-start","border-inline-start-color","border-inline-start-style","border-inline-start-width","border-inline-style","border-inline-width","border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right","border-right-color","border-right-style","border-right-width","border-spacing","border-style","border-top","border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width","border-width","bottom","box-decoration-break","box-shadow","box-sizing","break-after","break-before","break-inside","caption-side","caret-color","clear","clip","clip-path","clip-rule","color","column-count","column-fill","column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width","columns","contain","content","content-visibility","counter-increment","counter-reset","cue","cue-after","cue-before","cursor","direction","display","empty-cells","filter","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","float","flow","font","font-display","font-family","font-feature-settings","font-kerning","font-language-override","font-size","font-size-adjust","font-smoothing","font-stretch","font-style","font-synthesis","font-variant","font-variant-caps","font-variant-east-asian","font-variant-ligatures","font-variant-numeric","font-variant-position","font-variation-settings","font-weight","gap","glyph-orientation-vertical","grid","grid-area","grid-auto-columns","grid-auto-flow","grid-auto-rows","grid-column","grid-column-end","grid-column-start","grid-gap","grid-row","grid-row-end","grid-row-start","grid-template","grid-template-areas","grid-template-columns","grid-template-rows","hanging-punctuation","height","hyphens","icon","image-orientation","image-rendering","image-resolution","ime-mode","inline-size","isolation","justify-content","left","letter-spacing","line-break","line-height","list-style","list-style-image","list-style-position","list-style-type","margin","margin-block","margin-block-end","margin-block-start","margin-bottom","margin-inline","margin-inline-end","margin-inline-start","margin-left","margin-right","margin-top","marks","mask","mask-border","mask-border-mode","mask-border-outset","mask-border-repeat","mask-border-slice","mask-border-source","mask-border-width","mask-clip","mask-composite","mask-image","mask-mode","mask-origin","mask-position","mask-repeat","mask-size","mask-type","max-block-size","max-height","max-inline-size","max-width","min-block-size","min-height","min-inline-size","min-width","mix-blend-mode","nav-down","nav-index","nav-left","nav-right","nav-up","none","normal","object-fit","object-position","opacity","order","orphans","outline","outline-color","outline-offset","outline-style","outline-width","overflow","overflow-wrap","overflow-x","overflow-y","padding","padding-block","padding-block-end","padding-block-start","padding-bottom","padding-inline","padding-inline-end","padding-inline-start","padding-left","padding-right","padding-top","page-break-after","page-break-before","page-break-inside","pause","pause-after","pause-before","perspective","perspective-origin","pointer-events","position","quotes","resize","rest","rest-after","rest-before","right","row-gap","scroll-margin","scroll-margin-block","scroll-margin-block-end","scroll-margin-block-start","scroll-margin-bottom","scroll-margin-inline","scroll-margin-inline-end","scroll-margin-inline-start","scroll-margin-left","scroll-margin-right","scroll-margin-top","scroll-padding","scroll-padding-block","scroll-padding-block-end","scroll-padding-block-start","scroll-padding-bottom","scroll-padding-inline","scroll-padding-inline-end","scroll-padding-inline-start","scroll-padding-left","scroll-padding-right","scroll-padding-top","scroll-snap-align","scroll-snap-stop","scroll-snap-type","scrollbar-color","scrollbar-gutter","scrollbar-width","shape-image-threshold","shape-margin","shape-outside","speak","speak-as","src","tab-size","table-layout","text-align","text-align-all","text-align-last","text-combine-upright","text-decoration","text-decoration-color","text-decoration-line","text-decoration-style","text-emphasis","text-emphasis-color","text-emphasis-position","text-emphasis-style","text-indent","text-justify","text-orientation","text-overflow","text-rendering","text-shadow","text-transform","text-underline-position","top","transform","transform-box","transform-origin","transform-style","transition","transition-delay","transition-duration","transition-property","transition-timing-function","unicode-bidi","vertical-align","visibility","voice-balance","voice-duration","voice-family","voice-pitch","voice-range","voice-rate","voice-stress","voice-volume","white-space","widows","width","will-change","word-break","word-spacing","word-wrap","writing-mode","z-index"].reverse(),H3=Tm.concat(wm);const a8=["a","abbr","address","article","aside","audio","b","blockquote","body","button","canvas","caption","cite","code","dd","del","details","dfn","div","dl","dt","em","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","header","hgroup","html","i","iframe","img","input","ins","kbd","label","legend","li","main","mark","menu","nav","object","ol","p","q","quote","samp","section","span","strong","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","tr","ul","var","video"],s8=["any-hover","any-pointer","aspect-ratio","color","color-gamut","color-index","device-aspect-ratio","device-height","device-width","display-mode","forced-colors","grid","height","hover","inverted-colors","monochrome","orientation","overflow-block","overflow-inline","pointer","prefers-color-scheme","prefers-contrast","prefers-reduced-motion","prefers-reduced-transparency","resolution","scan","scripting","update","width","min-width","max-width","min-height","max-height"],i8=["active","any-link","blank","checked","current","default","defined","dir","disabled","drop","empty","enabled","first","first-child","first-of-type","fullscreen","future","focus","focus-visible","focus-within","has","host","host-context","hover","indeterminate","in-range","invalid","is","lang","last-child","last-of-type","left","link","local-link","not","nth-child","nth-col","nth-last-child","nth-last-col","nth-last-of-type","nth-of-type","only-child","only-of-type","optional","out-of-range","past","placeholder-shown","read-only","read-write","required","right","root","scope","target","target-within","user-invalid","valid","visited","where"],l8=["after","backdrop","before","cue","cue-region","first-letter","first-line","grammar-error","marker","part","placeholder","selection","slotted","spelling-error"],u8=["align-content","align-items","align-self","all","animation","animation-delay","animation-direction","animation-duration","animation-fill-mode","animation-iteration-count","animation-name","animation-play-state","animation-timing-function","backface-visibility","background","background-attachment","background-blend-mode","background-clip","background-color","background-image","background-origin","background-position","background-repeat","background-size","block-size","border","border-block","border-block-color","border-block-end","border-block-end-color","border-block-end-style","border-block-end-width","border-block-start","border-block-start-color","border-block-start-style","border-block-start-width","border-block-style","border-block-width","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius","border-bottom-style","border-bottom-width","border-collapse","border-color","border-image","border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width","border-inline","border-inline-color","border-inline-end","border-inline-end-color","border-inline-end-style","border-inline-end-width","border-inline-start","border-inline-start-color","border-inline-start-style","border-inline-start-width","border-inline-style","border-inline-width","border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right","border-right-color","border-right-style","border-right-width","border-spacing","border-style","border-top","border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width","border-width","bottom","box-decoration-break","box-shadow","box-sizing","break-after","break-before","break-inside","caption-side","caret-color","clear","clip","clip-path","clip-rule","color","column-count","column-fill","column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width","columns","contain","content","content-visibility","counter-increment","counter-reset","cue","cue-after","cue-before","cursor","direction","display","empty-cells","filter","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","float","flow","font","font-display","font-family","font-feature-settings","font-kerning","font-language-override","font-size","font-size-adjust","font-smoothing","font-stretch","font-style","font-synthesis","font-variant","font-variant-caps","font-variant-east-asian","font-variant-ligatures","font-variant-numeric","font-variant-position","font-variation-settings","font-weight","gap","glyph-orientation-vertical","grid","grid-area","grid-auto-columns","grid-auto-flow","grid-auto-rows","grid-column","grid-column-end","grid-column-start","grid-gap","grid-row","grid-row-end","grid-row-start","grid-template","grid-template-areas","grid-template-columns","grid-template-rows","hanging-punctuation","height","hyphens","icon","image-orientation","image-rendering","image-resolution","ime-mode","inline-size","isolation","justify-content","left","letter-spacing","line-break","line-height","list-style","list-style-image","list-style-position","list-style-type","margin","margin-block","margin-block-end","margin-block-start","margin-bottom","margin-inline","margin-inline-end","margin-inline-start","margin-left","margin-right","margin-top","marks","mask","mask-border","mask-border-mode","mask-border-outset","mask-border-repeat","mask-border-slice","mask-border-source","mask-border-width","mask-clip","mask-composite","mask-image","mask-mode","mask-origin","mask-position","mask-repeat","mask-size","mask-type","max-block-size","max-height","max-inline-size","max-width","min-block-size","min-height","min-inline-size","min-width","mix-blend-mode","nav-down","nav-index","nav-left","nav-right","nav-up","none","normal","object-fit","object-position","opacity","order","orphans","outline","outline-color","outline-offset","outline-style","outline-width","overflow","overflow-wrap","overflow-x","overflow-y","padding","padding-block","padding-block-end","padding-block-start","padding-bottom","padding-inline","padding-inline-end","padding-inline-start","padding-left","padding-right","padding-top","page-break-after","page-break-before","page-break-inside","pause","pause-after","pause-before","perspective","perspective-origin","pointer-events","position","quotes","resize","rest","rest-after","rest-before","right","row-gap","scroll-margin","scroll-margin-block","scroll-margin-block-end","scroll-margin-block-start","scroll-margin-bottom","scroll-margin-inline","scroll-margin-inline-end","scroll-margin-inline-start","scroll-margin-left","scroll-margin-right","scroll-margin-top","scroll-padding","scroll-padding-block","scroll-padding-block-end","scroll-padding-block-start","scroll-padding-bottom","scroll-padding-inline","scroll-padding-inline-end","scroll-padding-inline-start","scroll-padding-left","scroll-padding-right","scroll-padding-top","scroll-snap-align","scroll-snap-stop","scroll-snap-type","scrollbar-color","scrollbar-gutter","scrollbar-width","shape-image-threshold","shape-margin","shape-outside","speak","speak-as","src","tab-size","table-layout","text-align","text-align-all","text-align-last","text-combine-upright","text-decoration","text-decoration-color","text-decoration-line","text-decoration-style","text-emphasis","text-emphasis-color","text-emphasis-position","text-emphasis-style","text-indent","text-justify","text-orientation","text-overflow","text-rendering","text-shadow","text-transform","text-underline-position","top","transform","transform-box","transform-origin","transform-style","transition","transition-delay","transition-duration","transition-property","transition-timing-function","unicode-bidi","vertical-align","visibility","voice-balance","voice-duration","voice-family","voice-pitch","voice-range","voice-rate","voice-stress","voice-volume","white-space","widows","width","will-change","word-break","word-spacing","word-wrap","writing-mode","z-index"].reverse();function xm(t){return t?"string"==typeof t?t:t.source:null}function js(t){return fe("(?=",t,")")}function fe(...t){return t.map((n=>xm(n))).join("")}function it(...t){return"("+(function(t){const e=t[t.length-1];return"object"==typeof e&&e.constructor===Object?(t.splice(t.length-1,1),e):{}}(t).capture?"":"?:")+t.map((r=>xm(r))).join("|")+")"}const nc=t=>fe(/\b/,t,/\w$/.test(t)?/\b/:/\B/),m8=["Protocol","Type"].map(nc),Rm=["init","self"].map(nc),g8=["Any","Self"],rc=["actor","any","associatedtype","async","await",/as\?/,/as!/,"as","borrowing","break","case","catch","class","consume","consuming","continue","convenience","copy","default","defer","deinit","didSet","distributed","do","dynamic","each","else","enum","extension","fallthrough",/fileprivate\(set\)/,"fileprivate","final","for","func","get","guard","if","import","indirect","infix",/init\?/,/init!/,"inout",/internal\(set\)/,"internal","in","is","isolated","nonisolated","lazy","let","macro","mutating","nonmutating",/open\(set\)/,"open","operator","optional","override","postfix","precedencegroup","prefix",/private\(set\)/,"private","protocol",/public\(set\)/,"public","repeat","required","rethrows","return","set","some","static","struct","subscript","super","switch","throws","throw",/try\?/,/try!/,"try","typealias",/unowned\(safe\)/,/unowned\(unsafe\)/,"unowned","var","weak","where","while","willSet"],Lm=["false","nil","true"],h8=["assignment","associativity","higherThan","left","lowerThan","none","right"],E8=["#colorLiteral","#column","#dsohandle","#else","#elseif","#endif","#error","#file","#fileID","#fileLiteral","#filePath","#function","#if","#imageLiteral","#keyPath","#line","#selector","#sourceLocation","#warning"],Om=["abs","all","any","assert","assertionFailure","debugPrint","dump","fatalError","getVaList","isKnownUniquelyReferenced","max","min","numericCast","pointwiseMax","pointwiseMin","precondition","preconditionFailure","print","readLine","repeatElement","sequence","stride","swap","swift_unboxFromSwiftValueWithType","transcode","type","unsafeBitCast","unsafeDowncast","withExtendedLifetime","withUnsafeMutablePointer","withUnsafePointer","withVaList","withoutActuallyEscaping","zip"],km=it(/[/=\-+!*%<>&|^~?]/,/[\u00A1-\u00A7]/,/[\u00A9\u00AB]/,/[\u00AC\u00AE]/,/[\u00B0\u00B1]/,/[\u00B6\u00BB\u00BF\u00D7\u00F7]/,/[\u2016-\u2017]/,/[\u2020-\u2027]/,/[\u2030-\u203E]/,/[\u2041-\u2053]/,/[\u2055-\u205E]/,/[\u2190-\u23FF]/,/[\u2500-\u2775]/,/[\u2794-\u2BFF]/,/[\u2E00-\u2E7F]/,/[\u3001-\u3003]/,/[\u3008-\u3020]/,/[\u3030]/),Im=it(km,/[\u0300-\u036F]/,/[\u1DC0-\u1DFF]/,/[\u20D0-\u20FF]/,/[\uFE00-\uFE0F]/,/[\uFE20-\uFE2F]/),oc=fe(km,Im,"*"),Mm=it(/[a-zA-Z_]/,/[\u00A8\u00AA\u00AD\u00AF\u00B2-\u00B5\u00B7-\u00BA]/,/[\u00BC-\u00BE\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF]/,/[\u0100-\u02FF\u0370-\u167F\u1681-\u180D\u180F-\u1DBF]/,/[\u1E00-\u1FFF]/,/[\u200B-\u200D\u202A-\u202E\u203F-\u2040\u2054\u2060-\u206F]/,/[\u2070-\u20CF\u2100-\u218F\u2460-\u24FF\u2776-\u2793]/,/[\u2C00-\u2DFF\u2E80-\u2FFF]/,/[\u3004-\u3007\u3021-\u302F\u3031-\u303F\u3040-\uD7FF]/,/[\uF900-\uFD3D\uFD40-\uFDCF\uFDF0-\uFE1F\uFE30-\uFE44]/,/[\uFE47-\uFEFE\uFF00-\uFFFD]/),Ws=it(Mm,/\d/,/[\u0300-\u036F\u1DC0-\u1DFF\u20D0-\u20FF\uFE20-\uFE2F]/),cn=fe(Mm,Ws,"*"),ac=fe(/[A-Z]/,Ws,"*"),b8=["attached","autoclosure",fe(/convention\(/,it("swift","block","c"),/\)/),"discardableResult","dynamicCallable","dynamicMemberLookup","escaping","freestanding","frozen","GKInspectable","IBAction","IBDesignable","IBInspectable","IBOutlet","IBSegueAction","inlinable","main","nonobjc","NSApplicationMain","NSCopying","NSManaged",fe(/objc\(/,cn,/\)/),"objc","objcMembers","propertyWrapper","requires_stored_property_inits","resultBuilder","Sendable","testable","UIApplicationMain","unchecked","unknown","usableFromInline","warn_unqualified_access"],A8=["iOS","iOSApplicationExtension","macOS","macOSApplicationExtension","macCatalyst","macCatalystApplicationExtension","watchOS","watchOSApplicationExtension","tvOS","tvOSApplicationExtension","swift"];const Ks="[A-Za-z$_][0-9A-Za-z$_]*",Fm=["as","in","of","if","for","while","finally","var","new","function","do","return","void","else","break","catch","instanceof","with","throw","case","default","try","switch","continue","typeof","delete","let","yield","const","class","debugger","async","await","static","import","from","export","extends"],Bm=["true","false","null","undefined","NaN","Infinity"],Pm=["Object","Function","Boolean","Symbol","Math","Date","Number","BigInt","String","RegExp","Array","Float32Array","Float64Array","Int8Array","Uint8Array","Uint8ClampedArray","Int16Array","Int32Array","Uint16Array","Uint32Array","BigInt64Array","BigUint64Array","Set","Map","WeakSet","WeakMap","ArrayBuffer","SharedArrayBuffer","Atomics","DataView","JSON","Promise","Generator","GeneratorFunction","AsyncFunction","Reflect","Proxy","Intl","WebAssembly"],Um=["Error","EvalError","InternalError","RangeError","ReferenceError","SyntaxError","TypeError","URIError"],qm=["setInterval","setTimeout","clearInterval","clearTimeout","require","exports","eval","isFinite","isNaN","parseFloat","parseInt","decodeURI","decodeURIComponent","encodeURI","encodeURIComponent","escape","unescape"],Hm=["arguments","this","super","console","window","document","localStorage","sessionStorage","module","global"],Vm=[].concat(qm,Pm,Um);J.registerLanguage("apache",(function(t){const r={className:"number",begin:/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(:\d{1,5})?/};return{name:"Apache config",aliases:["apacheconf"],case_insensitive:!0,contains:[t.HASH_COMMENT_MODE,{className:"section",begin:/<\/?/,end:/>/,contains:[r,{className:"number",begin:/:\d{1,5}/},t.inherit(t.QUOTE_STRING_MODE,{relevance:0})]},{className:"attribute",begin:/\w+/,relevance:0,keywords:{_:["order","deny","allow","setenv","rewriterule","rewriteengine","rewritecond","documentroot","sethandler","errordocument","loadmodule","options","header","listen","serverroot","servername"]},starts:{end:/$/,relevance:0,keywords:{literal:"on off all deny allow"},contains:[{className:"meta",begin:/\s\[/,end:/\]$/},{className:"variable",begin:/[\$%]\{/,end:/\}/,contains:["self",{className:"number",begin:/[$%]\d+/}]},r,{className:"number",begin:/\b\d+/},t.QUOTE_STRING_MODE]}}],illegal:/\S/}})),J.registerLanguage("bash",(function(t){const e=t.regex,n={},r={begin:/\$\{/,end:/\}/,contains:["self",{begin:/:-/,contains:[n]}]};Object.assign(n,{className:"variable",variants:[{begin:e.concat(/\$[\w\d#@][\w\d_]*/,"(?![\\w\\d])(?![$])")},r]});const o={className:"subst",begin:/\$\(/,end:/\)/,contains:[t.BACKSLASH_ESCAPE]},a={begin:/<<-?\s*(?=\w+)/,starts:{contains:[t.END_SAME_AS_BEGIN({begin:/(\w+)/,end:/(\w+)/,className:"string"})]}},s={className:"string",begin:/"/,end:/"/,contains:[t.BACKSLASH_ESCAPE,n,o]};o.contains.push(s);const c={begin:/\$?\(\(/,end:/\)\)/,contains:[{begin:/\d+#[0-9a-f]+/,className:"number"},t.NUMBER_MODE,n]},d=t.SHEBANG({binary:`(${["fish","bash","zsh","sh","csh","ksh","tcsh","dash","scsh"].join("|")})`,relevance:10}),f={className:"function",begin:/\w[\w\d_]*\s*\(\s*\)\s*\{/,returnBegin:!0,contains:[t.inherit(t.TITLE_MODE,{begin:/\w[\w\d_]*/})],relevance:0};return{name:"Bash",aliases:["sh"],keywords:{$pattern:/\b[a-z][a-z0-9._-]+\b/,keyword:["if","then","else","elif","fi","for","while","until","in","do","done","case","esac","function","select"],literal:["true","false"],built_in:["break","cd","continue","eval","exec","exit","export","getopts","hash","pwd","readonly","return","shift","test","times","trap","umask","unset","alias","bind","builtin","caller","command","declare","echo","enable","help","let","local","logout","mapfile","printf","read","readarray","source","type","typeset","ulimit","unalias","set","shopt","autoload","bg","bindkey","bye","cap","chdir","clone","comparguments","compcall","compctl","compdescribe","compfiles","compgroups","compquote","comptags","comptry","compvalues","dirs","disable","disown","echotc","echoti","emulate","fc","fg","float","functions","getcap","getln","history","integer","jobs","kill","limit","log","noglob","popd","print","pushd","pushln","rehash","sched","setcap","setopt","stat","suspend","ttyctl","unfunction","unhash","unlimit","unsetopt","vared","wait","whence","where","which","zcompile","zformat","zftp","zle","zmodload","zparseopts","zprof","zpty","zregexparse","zsocket","zstyle","ztcp","chcon","chgrp","chown","chmod","cp","dd","df","dir","dircolors","ln","ls","mkdir","mkfifo","mknod","mktemp","mv","realpath","rm","rmdir","shred","sync","touch","truncate","vdir","b2sum","base32","base64","cat","cksum","comm","csplit","cut","expand","fmt","fold","head","join","md5sum","nl","numfmt","od","paste","ptx","pr","sha1sum","sha224sum","sha256sum","sha384sum","sha512sum","shuf","sort","split","sum","tac","tail","tr","tsort","unexpand","uniq","wc","arch","basename","chroot","date","dirname","du","echo","env","expr","factor","groups","hostid","id","link","logname","nice","nohup","nproc","pathchk","pinky","printenv","printf","pwd","readlink","runcon","seq","sleep","stat","stdbuf","stty","tee","test","timeout","tty","uname","unlink","uptime","users","who","whoami","yes"]},contains:[d,t.SHEBANG(),f,c,t.HASH_COMMENT_MODE,a,{match:/(\/[a-z._-]+)+/},s,{match:/\\"/},{className:"string",begin:/'/,end:/'/},{match:/\\'/},n]}})),J.registerLanguage("c",(function(t){const e=t.regex,n=t.COMMENT("//","$",{contains:[{begin:/\\\n/}]}),r="decltype\\(auto\\)",o="[a-zA-Z_]\\w*::",s="("+r+"|"+e.optional(o)+"[a-zA-Z_]\\w*"+e.optional("<[^<>]+>")+")",i={className:"type",variants:[{begin:"\\b[a-z\\d_]*_t\\b"},{match:/\batomic_[a-z]{3,6}\b/}]},u={className:"string",variants:[{begin:'(u8?|U|L)?"',end:'"',illegal:"\\n",contains:[t.BACKSLASH_ESCAPE]},{begin:"(u8?|U|L)?'(\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)|.)",end:"'",illegal:"."},t.END_SAME_AS_BEGIN({begin:/(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/,end:/\)([^()\\ ]{0,16})"/})]},c={className:"number",variants:[{begin:"\\b(0b[01']+)"},{begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)((ll|LL|l|L)(u|U)?|(u|U)(ll|LL|l|L)?|f|F|b|B)"},{begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"}],relevance:0},p={className:"meta",begin:/#\s*[a-z]+\b/,end:/$/,keywords:{keyword:"if else elif endif define undef warning error line pragma _Pragma ifdef ifndef include"},contains:[{begin:/\\\n/,relevance:0},t.inherit(u,{className:"string"}),{className:"string",begin:/<.*?>/},n,t.C_BLOCK_COMMENT_MODE]},d={className:"title",begin:e.optional(o)+t.IDENT_RE,relevance:0},f=e.optional(o)+t.IDENT_RE+"\\s*\\(",y={keyword:["asm","auto","break","case","continue","default","do","else","enum","extern","for","fortran","goto","if","inline","register","restrict","return","sizeof","struct","switch","typedef","union","volatile","while","_Alignas","_Alignof","_Atomic","_Generic","_Noreturn","_Static_assert","_Thread_local","alignas","alignof","noreturn","static_assert","thread_local","_Pragma"],type:["float","double","signed","unsigned","int","short","long","char","void","_Bool","_Complex","_Imaginary","_Decimal32","_Decimal64","_Decimal128","const","static","complex","bool","imaginary"],literal:"true false NULL",built_in:"std string wstring cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set pair bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap priority_queue make_pair array shared_ptr abort terminate abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf future isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf endl initializer_list unique_ptr"},h=[p,i,n,t.C_BLOCK_COMMENT_MODE,c,u],g={variants:[{begin:/=/,end:/;/},{begin:/\(/,end:/\)/},{beginKeywords:"new throw return else",end:/;/}],keywords:y,contains:h.concat([{begin:/\(/,end:/\)/,keywords:y,contains:h.concat(["self"]),relevance:0}]),relevance:0},E={begin:"("+s+"[\\*&\\s]+)+"+f,returnBegin:!0,end:/[{;=]/,excludeEnd:!0,keywords:y,illegal:/[^\w\s\*&:<>.]/,contains:[{begin:r,keywords:y,relevance:0},{begin:f,returnBegin:!0,contains:[t.inherit(d,{className:"title.function"})],relevance:0},{relevance:0,match:/,/},{className:"params",begin:/\(/,end:/\)/,keywords:y,relevance:0,contains:[n,t.C_BLOCK_COMMENT_MODE,u,c,i,{begin:/\(/,end:/\)/,keywords:y,relevance:0,contains:["self",n,t.C_BLOCK_COMMENT_MODE,u,c,i]}]},i,n,t.C_BLOCK_COMMENT_MODE,p]};return{name:"C",aliases:["h"],keywords:y,disableAutodetect:!0,illegal:"=]/,contains:[{beginKeywords:"final class struct"},t.TITLE_MODE]}]),exports:{preprocessor:p,strings:u,keywords:y}}})),J.registerLanguage("cpp",(function(t){const e=t.regex,n=t.COMMENT("//","$",{contains:[{begin:/\\\n/}]}),r="decltype\\(auto\\)",o="[a-zA-Z_]\\w*::",s="(?!struct)("+r+"|"+e.optional(o)+"[a-zA-Z_]\\w*"+e.optional("<[^<>]+>")+")",i={className:"type",begin:"\\b[a-z\\d_]*_t\\b"},u={className:"string",variants:[{begin:'(u8?|U|L)?"',end:'"',illegal:"\\n",contains:[t.BACKSLASH_ESCAPE]},{begin:"(u8?|U|L)?'(\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)|.)",end:"'",illegal:"."},t.END_SAME_AS_BEGIN({begin:/(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/,end:/\)([^()\\ ]{0,16})"/})]},c={className:"number",variants:[{begin:"\\b(0b[01']+)"},{begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)((ll|LL|l|L)(u|U)?|(u|U)(ll|LL|l|L)?|f|F|b|B)"},{begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"}],relevance:0},p={className:"meta",begin:/#\s*[a-z]+\b/,end:/$/,keywords:{keyword:"if else elif endif define undef warning error line pragma _Pragma ifdef ifndef include"},contains:[{begin:/\\\n/,relevance:0},t.inherit(u,{className:"string"}),{className:"string",begin:/<.*?>/},n,t.C_BLOCK_COMMENT_MODE]},d={className:"title",begin:e.optional(o)+t.IDENT_RE,relevance:0},f=e.optional(o)+t.IDENT_RE+"\\s*\\(",_={type:["bool","char","char16_t","char32_t","char8_t","double","float","int","long","short","void","wchar_t","unsigned","signed","const","static"],keyword:["alignas","alignof","and","and_eq","asm","atomic_cancel","atomic_commit","atomic_noexcept","auto","bitand","bitor","break","case","catch","class","co_await","co_return","co_yield","compl","concept","const_cast|10","consteval","constexpr","constinit","continue","decltype","default","delete","do","dynamic_cast|10","else","enum","explicit","export","extern","false","final","for","friend","goto","if","import","inline","module","mutable","namespace","new","noexcept","not","not_eq","nullptr","operator","or","or_eq","override","private","protected","public","reflexpr","register","reinterpret_cast|10","requires","return","sizeof","static_assert","static_cast|10","struct","switch","synchronized","template","this","thread_local","throw","transaction_safe","transaction_safe_dynamic","true","try","typedef","typeid","typename","union","using","virtual","volatile","while","xor","xor_eq"],literal:["NULL","false","nullopt","nullptr","true"],built_in:["_Pragma"],_type_hints:["any","auto_ptr","barrier","binary_semaphore","bitset","complex","condition_variable","condition_variable_any","counting_semaphore","deque","false_type","future","imaginary","initializer_list","istringstream","jthread","latch","lock_guard","multimap","multiset","mutex","optional","ostringstream","packaged_task","pair","promise","priority_queue","queue","recursive_mutex","recursive_timed_mutex","scoped_lock","set","shared_future","shared_lock","shared_mutex","shared_timed_mutex","shared_ptr","stack","string_view","stringstream","timed_mutex","thread","true_type","tuple","unique_lock","unique_ptr","unordered_map","unordered_multimap","unordered_multiset","unordered_set","variant","vector","weak_ptr","wstring","wstring_view"]},N={className:"function.dispatch",relevance:0,keywords:{_hint:["abort","abs","acos","apply","as_const","asin","atan","atan2","calloc","ceil","cerr","cin","clog","cos","cosh","cout","declval","endl","exchange","exit","exp","fabs","floor","fmod","forward","fprintf","fputs","free","frexp","fscanf","future","invoke","isalnum","isalpha","iscntrl","isdigit","isgraph","islower","isprint","ispunct","isspace","isupper","isxdigit","labs","launder","ldexp","log","log10","make_pair","make_shared","make_shared_for_overwrite","make_tuple","make_unique","malloc","memchr","memcmp","memcpy","memset","modf","move","pow","printf","putchar","puts","realloc","scanf","sin","sinh","snprintf","sprintf","sqrt","sscanf","std","stderr","stdin","stdout","strcat","strchr","strcmp","strcpy","strcspn","strlen","strncat","strncmp","strncpy","strpbrk","strrchr","strspn","strstr","swap","tan","tanh","terminate","to_underlying","tolower","toupper","vfprintf","visit","vprintf","vsprintf"]},begin:e.concat(/\b/,/(?!decltype)/,/(?!if)/,/(?!for)/,/(?!switch)/,/(?!while)/,t.IDENT_RE,e.lookahead(/(<[^<>]+>|)\s*\(/))},v=[N,p,i,n,t.C_BLOCK_COMMENT_MODE,c,u],T={variants:[{begin:/=/,end:/;/},{begin:/\(/,end:/\)/},{beginKeywords:"new throw return else",end:/;/}],keywords:_,contains:v.concat([{begin:/\(/,end:/\)/,keywords:_,contains:v.concat(["self"]),relevance:0}]),relevance:0},R={className:"function",begin:"("+s+"[\\*&\\s]+)+"+f,returnBegin:!0,end:/[{;=]/,excludeEnd:!0,keywords:_,illegal:/[^\w\s\*&:<>.]/,contains:[{begin:r,keywords:_,relevance:0},{begin:f,returnBegin:!0,contains:[d],relevance:0},{begin:/::/,relevance:0},{begin:/:/,endsWithParent:!0,contains:[u,c]},{relevance:0,match:/,/},{className:"params",begin:/\(/,end:/\)/,keywords:_,relevance:0,contains:[n,t.C_BLOCK_COMMENT_MODE,u,c,i,{begin:/\(/,end:/\)/,keywords:_,relevance:0,contains:["self",n,t.C_BLOCK_COMMENT_MODE,u,c,i]}]},i,n,t.C_BLOCK_COMMENT_MODE,p]};return{name:"C++",aliases:["cc","c++","h++","hpp","hh","hxx","cxx"],keywords:_,illegal:"",keywords:_,contains:["self",i]},{begin:t.IDENT_RE+"::",keywords:_},{match:[/\b(?:enum(?:\s+(?:class|struct))?|class|struct|union)/,/\s+/,/\w+/],className:{1:"keyword",3:"title.class"}}])}})),J.registerLanguage("csharp",(function(t){const s={keyword:["abstract","as","base","break","case","catch","class","const","continue","do","else","event","explicit","extern","finally","fixed","for","foreach","goto","if","implicit","in","interface","internal","is","lock","namespace","new","operator","out","override","params","private","protected","public","readonly","record","ref","return","scoped","sealed","sizeof","stackalloc","static","struct","switch","this","throw","try","typeof","unchecked","unsafe","using","virtual","void","volatile","while"].concat(["add","alias","and","ascending","async","await","by","descending","equals","from","get","global","group","init","into","join","let","nameof","not","notnull","on","or","orderby","partial","remove","select","set","unmanaged","value|0","var","when","where","with","yield"]),built_in:["bool","byte","char","decimal","delegate","double","dynamic","enum","float","int","long","nint","nuint","object","sbyte","short","string","ulong","uint","ushort"],literal:["default","false","null","true"]},i=t.inherit(t.TITLE_MODE,{begin:"[a-zA-Z](\\.?\\w)*"}),l={className:"number",variants:[{begin:"\\b(0b[01']+)"},{begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)(u|U|l|L|ul|UL|f|F|b|B)"},{begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"}],relevance:0},u={className:"string",begin:'@"',end:'"',contains:[{begin:'""'}]},c=t.inherit(u,{illegal:/\n/}),p={className:"subst",begin:/\{/,end:/\}/,keywords:s},d=t.inherit(p,{illegal:/\n/}),f={className:"string",begin:/\$"/,end:'"',illegal:/\n/,contains:[{begin:/\{\{/},{begin:/\}\}/},t.BACKSLASH_ESCAPE,d]},b={className:"string",begin:/\$@"/,end:'"',contains:[{begin:/\{\{/},{begin:/\}\}/},{begin:'""'},p]},A=t.inherit(b,{illegal:/\n/,contains:[{begin:/\{\{/},{begin:/\}\}/},{begin:'""'},d]});p.contains=[b,f,u,t.APOS_STRING_MODE,t.QUOTE_STRING_MODE,l,t.C_BLOCK_COMMENT_MODE],d.contains=[A,f,c,t.APOS_STRING_MODE,t.QUOTE_STRING_MODE,l,t.inherit(t.C_BLOCK_COMMENT_MODE,{illegal:/\n/})];const y={variants:[b,f,u,t.APOS_STRING_MODE,t.QUOTE_STRING_MODE]},h={begin:"<",end:">",contains:[{beginKeywords:"in out"},i]},g=t.IDENT_RE+"(<"+t.IDENT_RE+"(\\s*,\\s*"+t.IDENT_RE+")*>)?(\\[\\])?",E={begin:"@"+t.IDENT_RE,relevance:0};return{name:"C#",aliases:["cs","c#"],keywords:s,illegal:/::/,contains:[t.COMMENT("///","$",{returnBegin:!0,contains:[{className:"doctag",variants:[{begin:"///",relevance:0},{begin:"\x3c!--|--\x3e"},{begin:""}]}]}),t.C_LINE_COMMENT_MODE,t.C_BLOCK_COMMENT_MODE,{className:"meta",begin:"#",end:"$",keywords:{keyword:"if else elif endif define undef warning error line region endregion pragma checksum"}},y,l,{beginKeywords:"class interface",relevance:0,end:/[{;=]/,illegal:/[^\s:,]/,contains:[{beginKeywords:"where class"},i,h,t.C_LINE_COMMENT_MODE,t.C_BLOCK_COMMENT_MODE]},{beginKeywords:"namespace",relevance:0,end:/[{;=]/,illegal:/[^\s:]/,contains:[i,t.C_LINE_COMMENT_MODE,t.C_BLOCK_COMMENT_MODE]},{beginKeywords:"record",relevance:0,end:/[{;=]/,illegal:/[^\s:]/,contains:[i,h,t.C_LINE_COMMENT_MODE,t.C_BLOCK_COMMENT_MODE]},{className:"meta",begin:"^\\s*\\[(?=[\\w])",excludeBegin:!0,end:"\\]",excludeEnd:!0,contains:[{className:"string",begin:/"/,end:/"/}]},{beginKeywords:"new return throw await else",relevance:0},{className:"function",begin:"("+g+"\\s+)+"+t.IDENT_RE+"\\s*(<[^=]+>\\s*)?\\(",returnBegin:!0,end:/\s*[{;=]/,excludeEnd:!0,keywords:s,contains:[{beginKeywords:["public","private","protected","static","internal","protected","abstract","async","extern","override","unsafe","virtual","new","sealed","partial"].join(" "),relevance:0},{begin:t.IDENT_RE+"\\s*(<[^=]+>\\s*)?\\(",returnBegin:!0,contains:[t.TITLE_MODE,h],relevance:0},{match:/\(\)/},{className:"params",begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:s,relevance:0,contains:[y,l,t.C_BLOCK_COMMENT_MODE]},t.C_LINE_COMMENT_MODE,t.C_BLOCK_COMMENT_MODE]},E]}})),J.registerLanguage("css",(function(t){const e=t.regex,n=(t=>({IMPORTANT:{scope:"meta",begin:"!important"},BLOCK_COMMENT:t.C_BLOCK_COMMENT_MODE,HEXCOLOR:{scope:"number",begin:/#(([0-9a-fA-F]{3,4})|(([0-9a-fA-F]{2}){3,4}))\b/},FUNCTION_DISPATCH:{className:"built_in",begin:/[\w-]+(?=\()/},ATTRIBUTE_SELECTOR_MODE:{scope:"selector-attr",begin:/\[/,end:/\]/,illegal:"$",contains:[t.APOS_STRING_MODE,t.QUOTE_STRING_MODE]},CSS_NUMBER_MODE:{scope:"number",begin:t.NUMBER_RE+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",relevance:0},CSS_VARIABLE:{className:"attr",begin:/--[A-Za-z_][A-Za-z0-9_-]*/}}))(t),i=[t.APOS_STRING_MODE,t.QUOTE_STRING_MODE];return{name:"CSS",case_insensitive:!0,illegal:/[=|'\$]/,keywords:{keyframePosition:"from to"},classNameAliases:{keyframePosition:"selector-tag"},contains:[n.BLOCK_COMMENT,{begin:/-(webkit|moz|ms|o)-(?=[a-z])/},n.CSS_NUMBER_MODE,{className:"selector-id",begin:/#[A-Za-z0-9_-]+/,relevance:0},{className:"selector-class",begin:"\\.[a-zA-Z-][a-zA-Z0-9_-]*",relevance:0},n.ATTRIBUTE_SELECTOR_MODE,{className:"selector-pseudo",variants:[{begin:":("+_3.join("|")+")"},{begin:":(:)?("+v3.join("|")+")"}]},n.CSS_VARIABLE,{className:"attribute",begin:"\\b("+y3.join("|")+")\\b"},{begin:/:/,end:/[;}{]/,contains:[n.BLOCK_COMMENT,n.HEXCOLOR,n.IMPORTANT,n.CSS_NUMBER_MODE,...i,{begin:/(url|data-uri)\(/,end:/\)/,relevance:0,keywords:{built_in:"url data-uri"},contains:[...i,{className:"string",begin:/[^)]/,endsWithParent:!0,excludeEnd:!0}]},n.FUNCTION_DISPATCH]},{begin:e.lookahead(/@/),end:"[{;]",relevance:0,illegal:/:/,contains:[{className:"keyword",begin:/@-?\w[\w]*(-\w+)*/},{begin:/\s/,endsWithParent:!0,excludeEnd:!0,relevance:0,keywords:{$pattern:/[a-z-]+/,keyword:"and or not only",attribute:A3.join(" ")},contains:[{begin:/[a-z-]+(?=:)/,className:"attribute"},...i,n.CSS_NUMBER_MODE]}]},{className:"selector-tag",begin:"\\b("+b3.join("|")+")\\b"}]}})),J.registerLanguage("diff",(function(t){const e=t.regex;return{name:"Diff",aliases:["patch"],contains:[{className:"meta",relevance:10,match:e.either(/^@@ +-\d+,\d+ +\+\d+,\d+ +@@/,/^\*\*\* +\d+,\d+ +\*\*\*\*$/,/^--- +\d+,\d+ +----$/)},{className:"comment",variants:[{begin:e.either(/Index: /,/^index/,/={3,}/,/^-{3}/,/^\*{3} /,/^\+{3}/,/^diff --git/),end:/$/},{match:/^\*{15}$/}]},{className:"addition",begin:/^\+/,end:/$/},{className:"deletion",begin:/^-/,end:/$/},{className:"addition",begin:/^!/,end:/$/}]}})),J.registerLanguage("go",(function(t){const a={keyword:["break","case","chan","const","continue","default","defer","else","fallthrough","for","func","go","goto","if","import","interface","map","package","range","return","select","struct","switch","type","var"],type:["bool","byte","complex64","complex128","error","float32","float64","int8","int16","int32","int64","string","uint8","uint16","uint32","uint64","int","uint","uintptr","rune"],literal:["true","false","iota","nil"],built_in:["append","cap","close","complex","copy","imag","len","make","new","panic","print","println","real","recover","delete"]};return{name:"Go",aliases:["golang"],keywords:a,illegal:")?",/~~~/g,2),l={keyword:["synchronized","abstract","private","var","static","if","const ","for","while","strictfp","finally","protected","import","native","final","void","enum","else","break","transient","catch","instanceof","volatile","case","assert","package","default","public","try","switch","continue","throws","protected","public","private","module","requires","exports","do","sealed","yield","permits"],literal:["false","true","null"],type:["char","boolean","long","float","int","byte","short","double"],built_in:["super","this"]},u={className:"meta",begin:"@"+n,contains:[{begin:/\(/,end:/\)/,contains:["self"]}]},c={className:"params",begin:/\(/,end:/\)/,keywords:l,relevance:0,contains:[t.C_BLOCK_COMMENT_MODE],endsParent:!0};return{name:"Java",aliases:["jsp"],keywords:l,illegal:/<\/|#/,contains:[t.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{begin:/\w+@/,relevance:0},{className:"doctag",begin:"@[A-Za-z]+"}]}),{begin:/import java\.[a-z]+\./,keywords:"import",relevance:2},t.C_LINE_COMMENT_MODE,t.C_BLOCK_COMMENT_MODE,{begin:/"""/,end:/"""/,className:"string",contains:[t.BACKSLASH_ESCAPE]},t.APOS_STRING_MODE,t.QUOTE_STRING_MODE,{match:[/\b(?:class|interface|enum|extends|implements|new)/,/\s+/,n],className:{1:"keyword",3:"title.class"}},{match:/non-sealed/,scope:"keyword"},{begin:[e.concat(/(?!else)/,n),/\s+/,n,/\s+/,/=(?!=)/],className:{1:"type",3:"variable",5:"operator"}},{begin:[/record/,/\s+/,n],className:{1:"keyword",3:"title.class"},contains:[c,t.C_LINE_COMMENT_MODE,t.C_BLOCK_COMMENT_MODE]},{beginKeywords:"new throw return else",relevance:0},{begin:["(?:"+r+"\\s+)",t.UNDERSCORE_IDENT_RE,/\s*(?=\()/],className:{2:"title.function"},keywords:l,contains:[{className:"params",begin:/\(/,end:/\)/,keywords:l,relevance:0,contains:[u,t.APOS_STRING_MODE,t.QUOTE_STRING_MODE,vm,t.C_BLOCK_COMMENT_MODE]},t.C_LINE_COMMENT_MODE,t.C_BLOCK_COMMENT_MODE]},vm,u]}})),J.registerLanguage("javascript",(function(t){const e=t.regex,r=Dm,o_begin="<>",o_end="",s={begin:/<[A-Za-z0-9\\._:-]+/,end:/\/[A-Za-z0-9\\._:-]+>|\/>/,isTrulyOpeningTag:(S,C)=>{const L=S[0].length+S.index,k=S.input[L];if("<"===k||","===k)return void C.ignoreMatch();let $;">"===k&&(((S,{after:C})=>{const L="",x={match:[/const|var|let/,/\s+/,r,/\s*/,/=\s*/,/(async\s*)?/,e.lookahead(B)],keywords:"async",className:{1:"keyword",3:"title.function"},contains:[v]};var S;return{name:"JavaScript",aliases:["js","jsx","mjs","cjs"],keywords:i,exports:{PARAMS_CONTAINS:N,CLASS_REFERENCE:R},illegal:/#(?![$_A-z])/,contains:[t.SHEBANG({label:"shebang",binary:"node",relevance:5}),{label:"use_strict",className:"meta",relevance:10,begin:/^\s*['"]use (strict|asm)['"]/},t.APOS_STRING_MODE,t.QUOTE_STRING_MODE,f,b,A,y,g,{match:/\$\d+/},p,R,{className:"attr",begin:r+e.lookahead(":"),relevance:0},x,{begin:"("+t.RE_STARTERS_RE+"|\\b(case|return|throw)\\b)\\s*",keywords:"return throw case",relevance:0,contains:[g,t.REGEXP_MODE,{className:"function",begin:B,returnBegin:!0,end:"\\s*=>",contains:[{className:"params",variants:[{begin:t.UNDERSCORE_IDENT_RE,relevance:0},{className:null,begin:/\(\s*\)/,skip:!0},{begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:i,contains:N}]}]},{begin:/,/,relevance:0},{match:/\s+/,relevance:0},{variants:[{begin:o_begin,end:o_end},{match:/<[A-Za-z0-9\\._:-]+\s*\/>/},{begin:s.begin,"on:begin":s.isTrulyOpeningTag,end:s.end}],subLanguage:"xml",contains:[{begin:s.begin,end:s.end,skip:!0,contains:["self"]}]}]},I,{beginKeywords:"while if switch catch for"},{begin:"\\b(?!function)"+t.UNDERSCORE_IDENT_RE+"\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)\\s*\\{",returnBegin:!0,label:"func.def",contains:[v,t.inherit(t.TITLE_MODE,{begin:r,className:"title.function"})]},{match:/\.\.\./,relevance:0},O,{match:"\\$"+r,relevance:0},{match:[/\bconstructor(?=\s*\()/],className:{1:"title.function"},contains:[v]},K,{relevance:0,match:/\b[A-Z][A-Z_0-9]+\b/,className:"variable.constant"},T,V,{match:/\$[(.]/}]}})),J.registerLanguage("json",(function(t){const r=["true","false","null"],o={scope:"literal",beginKeywords:r.join(" ")};return{name:"JSON",keywords:{literal:r},contains:[{className:"attr",begin:/"(\\.|[^\\"\r\n])*"(?=\s*:)/,relevance:1.01},{match:/[{}[\],:]/,className:"punctuation",relevance:0},t.QUOTE_STRING_MODE,o,t.C_NUMBER_MODE,t.C_LINE_COMMENT_MODE,t.C_BLOCK_COMMENT_MODE],illegal:"\\S"}})),J.registerLanguage("kotlin",(function(t){const e={keyword:"abstract as val var vararg get set class object open private protected public noinline crossinline dynamic final enum if else do while for when throw try catch finally import package is in fun override companion reified inline lateinit init interface annotation data sealed internal infix operator out by constructor super tailrec where const inner suspend typealias external expect actual",built_in:"Byte Short Char Int Long Boolean Float Double Void Unit Nothing",literal:"true false null"},r={className:"symbol",begin:t.UNDERSCORE_IDENT_RE+"@"},o={className:"subst",begin:/\$\{/,end:/\}/,contains:[t.C_NUMBER_MODE]},a={className:"variable",begin:"\\$"+t.UNDERSCORE_IDENT_RE},s={className:"string",variants:[{begin:'"""',end:'"""(?=[^"])',contains:[a,o]},{begin:"'",end:"'",illegal:/\n/,contains:[t.BACKSLASH_ESCAPE]},{begin:'"',end:'"',illegal:/\n/,contains:[t.BACKSLASH_ESCAPE,a,o]}]};o.contains.push(s);const i={className:"meta",begin:"@(?:file|property|field|get|set|receiver|param|setparam|delegate)\\s*:(?:\\s*"+t.UNDERSCORE_IDENT_RE+")?"},l={className:"meta",begin:"@"+t.UNDERSCORE_IDENT_RE,contains:[{begin:/\(/,end:/\)/,contains:[t.inherit(s,{className:"string"}),"self"]}]},u=M3,c=t.COMMENT("/\\*","\\*/",{contains:[t.C_BLOCK_COMMENT_MODE]}),p={variants:[{className:"type",begin:t.UNDERSCORE_IDENT_RE},{begin:/\(/,end:/\)/,contains:[]}]},d=p;return d.variants[1].contains=[p],p.variants[1].contains=[d],{name:"Kotlin",aliases:["kt","kts"],keywords:e,contains:[t.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{className:"doctag",begin:"@[A-Za-z]+"}]}),t.C_LINE_COMMENT_MODE,c,{className:"keyword",begin:/\b(break|continue|return|this)\b/,starts:{contains:[{className:"symbol",begin:/@\w+/}]}},r,i,l,{className:"function",beginKeywords:"fun",end:"[(]|$",returnBegin:!0,excludeEnd:!0,keywords:e,relevance:5,contains:[{begin:t.UNDERSCORE_IDENT_RE+"\\s*\\(",returnBegin:!0,relevance:0,contains:[t.UNDERSCORE_TITLE_MODE]},{className:"type",begin://,keywords:"reified",relevance:0},{className:"params",begin:/\(/,end:/\)/,endsParent:!0,keywords:e,relevance:0,contains:[{begin:/:/,end:/[=,\/]/,endsWithParent:!0,contains:[p,t.C_LINE_COMMENT_MODE,c],relevance:0},t.C_LINE_COMMENT_MODE,c,i,l,s,t.C_NUMBER_MODE]},c]},{begin:[/class|interface|trait/,/\s+/,t.UNDERSCORE_IDENT_RE],beginScope:{3:"title.class"},keywords:"class interface trait",end:/[:\{(]|$/,excludeEnd:!0,illegal:"extends implements",contains:[{beginKeywords:"public protected internal private constructor"},t.UNDERSCORE_TITLE_MODE,{className:"type",begin://,excludeBegin:!0,excludeEnd:!0,relevance:0},{className:"type",begin:/[,:]\s*/,end:/[<\(,){\s]|$/,excludeBegin:!0,returnEnd:!0},i,l]},s,{className:"meta",begin:"^#!/usr/bin/env",end:"$",illegal:"\n"},u]}})),J.registerLanguage("less",(function(t){const e=(t=>({IMPORTANT:{scope:"meta",begin:"!important"},BLOCK_COMMENT:t.C_BLOCK_COMMENT_MODE,HEXCOLOR:{scope:"number",begin:/#(([0-9a-fA-F]{3,4})|(([0-9a-fA-F]{2}){3,4}))\b/},FUNCTION_DISPATCH:{className:"built_in",begin:/[\w-]+(?=\()/},ATTRIBUTE_SELECTOR_MODE:{scope:"selector-attr",begin:/\[/,end:/\]/,illegal:"$",contains:[t.APOS_STRING_MODE,t.QUOTE_STRING_MODE]},CSS_NUMBER_MODE:{scope:"number",begin:t.NUMBER_RE+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",relevance:0},CSS_VARIABLE:{className:"attr",begin:/--[A-Za-z_][A-Za-z0-9_-]*/}}))(t),n=H3,o="[\\w-]+",a="("+o+"|@\\{"+o+"\\})",s=[],i=[],l=function(E){return{className:"string",begin:"~?"+E+".*?"+E}},u=function(E,_,N){return{className:E,begin:_,relevance:N}},c={$pattern:/[a-z-]+/,keyword:"and or not only",attribute:U3.join(" ")},p={begin:"\\(",end:"\\)",contains:i,keywords:c,relevance:0};i.push(t.C_LINE_COMMENT_MODE,t.C_BLOCK_COMMENT_MODE,l("'"),l('"'),e.CSS_NUMBER_MODE,{begin:"(url|data-uri)\\(",starts:{className:"string",end:"[\\)\\n]",excludeEnd:!0}},e.HEXCOLOR,p,u("variable","@@?"+o,10),u("variable","@\\{"+o+"\\}"),u("built_in","~?`[^`]*?`"),{className:"attribute",begin:o+"\\s*:",end:":",returnBegin:!0,excludeEnd:!0},e.IMPORTANT,{beginKeywords:"and not"},e.FUNCTION_DISPATCH);const d=i.concat({begin:/\{/,end:/\}/,contains:s}),f={beginKeywords:"when",endsWithParent:!0,contains:[{beginKeywords:"and not"}].concat(i)},b={begin:a+"\\s*:",returnBegin:!0,end:/[;}]/,relevance:0,contains:[{begin:/-(webkit|moz|ms|o)-/},e.CSS_VARIABLE,{className:"attribute",begin:"\\b("+q3.join("|")+")\\b",end:/(?=:)/,starts:{endsWithParent:!0,illegal:"[<=$]",relevance:0,contains:i}}]},A={className:"keyword",begin:"@(import|media|charset|font-face|(-[a-z]+-)?keyframes|supports|document|namespace|page|viewport|host)\\b",starts:{end:"[;{}]",keywords:c,returnEnd:!0,contains:i,relevance:0}},y={className:"variable",variants:[{begin:"@"+o+"\\s*:",relevance:15},{begin:"@"+o}],starts:{end:"[;}]",returnEnd:!0,contains:d}},h={variants:[{begin:"[\\.#:&\\[>]",end:"[;{}]"},{begin:a,end:/\{/}],returnBegin:!0,returnEnd:!0,illegal:"[<='$\"]",relevance:0,contains:[t.C_LINE_COMMENT_MODE,t.C_BLOCK_COMMENT_MODE,f,u("keyword","all\\b"),u("variable","@\\{"+o+"\\}"),{begin:"\\b("+P3.join("|")+")\\b",className:"selector-tag"},e.CSS_NUMBER_MODE,u("selector-tag",a,0),u("selector-id","#"+a),u("selector-class","\\."+a,0),u("selector-tag","&",0),e.ATTRIBUTE_SELECTOR_MODE,{className:"selector-pseudo",begin:":("+Tm.join("|")+")"},{className:"selector-pseudo",begin:":(:)?("+wm.join("|")+")"},{begin:/\(/,end:/\)/,relevance:0,contains:d},{begin:"!important"},e.FUNCTION_DISPATCH]},g={begin:o+`:(:)?(${n.join("|")})`,returnBegin:!0,contains:[h]};return s.push(t.C_LINE_COMMENT_MODE,t.C_BLOCK_COMMENT_MODE,A,y,g,b,h,f,e.FUNCTION_DISPATCH),{name:"Less",case_insensitive:!0,illegal:"[=>'/<($\"]",contains:s}})),J.registerLanguage("lua",(function(t){const e="\\[=*\\[",n="\\]=*\\]",r={begin:e,end:n,contains:["self"]},o=[t.COMMENT("--(?!"+e+")","$"),t.COMMENT("--"+e,n,{contains:[r],relevance:10})];return{name:"Lua",keywords:{$pattern:t.UNDERSCORE_IDENT_RE,literal:"true false nil",keyword:"and break do else elseif end for goto if in local not or repeat return then until while",built_in:"_G _ENV _VERSION __index __newindex __mode __call __metatable __tostring __len __gc __add __sub __mul __div __mod __pow __concat __unm __eq __lt __le assert collectgarbage dofile error getfenv getmetatable ipairs load loadfile loadstring module next pairs pcall print rawequal rawget rawset require select setfenv setmetatable tonumber tostring type unpack xpcall arg self coroutine resume yield status wrap create running debug getupvalue debug sethook getmetatable gethook setmetatable setlocal traceback setfenv getinfo setupvalue getlocal getregistry getfenv io lines write close flush open output type read stderr stdin input stdout popen tmpfile math log max acos huge ldexp pi cos tanh pow deg tan cosh sinh random randomseed frexp ceil floor rad abs sqrt modf asin min mod fmod log10 atan2 exp sin atan os exit setlocale date getenv difftime remove time clock tmpname rename execute package preload loadlib loaded loaders cpath config path seeall string sub upper len gfind rep find match char dump gmatch reverse byte format gsub lower table setn insert getn foreachi maxn foreach concat sort remove"},contains:o.concat([{className:"function",beginKeywords:"function",end:"\\)",contains:[t.inherit(t.TITLE_MODE,{begin:"([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*"}),{className:"params",begin:"\\(",endsWithParent:!0,contains:o}].concat(o)},t.C_NUMBER_MODE,t.APOS_STRING_MODE,t.QUOTE_STRING_MODE,{className:"string",begin:e,end:n,contains:[r],relevance:5}])}})),J.registerLanguage("makefile",(function(t){const e={className:"variable",variants:[{begin:"\\$\\("+t.UNDERSCORE_IDENT_RE+"\\)",contains:[t.BACKSLASH_ESCAPE]},{begin:/\$[@%",subLanguage:"xml",relevance:0},l={variants:[{begin:/\[.+?\]\[.*?\]/,relevance:0},{begin:/\[.+?\]\(((data|javascript|mailto):|(?:http|ftp)s?:\/\/).*?\)/,relevance:2},{begin:t.regex.concat(/\[.+?\]\(/,/[A-Za-z][A-Za-z0-9+.-]*/,/:\/\/.*?\)/),relevance:2},{begin:/\[.+?\]\([./?&#].*?\)/,relevance:1},{begin:/\[.*?\]\(.*?\)/,relevance:0}],returnBegin:!0,contains:[{match:/\[(?=\])/},{className:"string",relevance:0,begin:"\\[",end:"\\]",excludeBegin:!0,returnEnd:!0},{className:"link",relevance:0,begin:"\\]\\(",end:"\\)",excludeBegin:!0,excludeEnd:!0},{className:"symbol",relevance:0,begin:"\\]\\[",end:"\\]",excludeBegin:!0,excludeEnd:!0}]},u={className:"strong",contains:[],variants:[{begin:/_{2}(?!\s)/,end:/_{2}/},{begin:/\*{2}(?!\s)/,end:/\*{2}/}]},c={className:"emphasis",contains:[],variants:[{begin:/\*(?![*\s])/,end:/\*/},{begin:/_(?![_\s])/,end:/_/,relevance:0}]},p=t.inherit(u,{contains:[]}),d=t.inherit(c,{contains:[]});u.contains.push(d),c.contains.push(p);let f=[n,l];return[u,c,p,d].forEach((y=>{y.contains=y.contains.concat(f)})),f=f.concat(u,c),{name:"Markdown",aliases:["md","mkdown","mkd"],contains:[{className:"section",variants:[{begin:"^#{1,6}",end:"$",contains:f},{begin:"(?=^.+?\\n[=-]{2,}$)",contains:[{begin:"^[=-]*$"},{begin:"^",end:"\\n",contains:f}]}]},n,{className:"bullet",begin:"^[ \t]*([*+-]|(\\d+\\.))(?=\\s+)",end:"\\s+",excludeEnd:!0},u,c,{className:"quote",begin:"^>\\s+",contains:f,end:"$"},{className:"code",variants:[{begin:"(`{3,})[^`](.|\\n)*?\\1`*[ ]*"},{begin:"(~{3,})[^~](.|\\n)*?\\1~*[ ]*"},{begin:"```",end:"```+[ ]*$"},{begin:"~~~",end:"~~~+[ ]*$"},{begin:"`.+?`"},{begin:"(?=^( {4}|\\t))",contains:[{begin:"^( {4}|\\t)",end:"(\\n)$"}],relevance:0}]},{begin:"^[-\\*]{3,}",end:"$"},l,{begin:/^\[[^\n]+\]:/,returnBegin:!0,contains:[{className:"symbol",begin:/\[/,end:/\]/,excludeBegin:!0,excludeEnd:!0},{className:"link",begin:/:\s*/,end:/$/,excludeBegin:!0}]}]}})),J.registerLanguage("nginx",(function(t){const e=t.regex,n={className:"variable",variants:[{begin:/\$\d+/},{begin:/\$\{\w+\}/},{begin:e.concat(/[$@]/,t.UNDERSCORE_IDENT_RE)}]},o={endsWithParent:!0,keywords:{$pattern:/[a-z_]{2,}|\/dev\/poll/,literal:["on","off","yes","no","true","false","none","blocked","debug","info","notice","warn","error","crit","select","break","last","permanent","redirect","kqueue","rtsig","epoll","poll","/dev/poll"]},relevance:0,illegal:"=>",contains:[t.HASH_COMMENT_MODE,{className:"string",contains:[t.BACKSLASH_ESCAPE,n],variants:[{begin:/"/,end:/"/},{begin:/'/,end:/'/}]},{begin:"([a-z]+):/",end:"\\s",endsWithParent:!0,excludeEnd:!0,contains:[n]},{className:"regexp",contains:[t.BACKSLASH_ESCAPE,n],variants:[{begin:"\\s\\^",end:"\\s|\\{|;",returnEnd:!0},{begin:"~\\*?\\s+",end:"\\s|\\{|;",returnEnd:!0},{begin:"\\*(\\.[a-z\\-]+)+"},{begin:"([a-z\\-]+\\.)+\\*"}]},{className:"number",begin:"\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?\\b"},{className:"number",begin:"\\b\\d+[kKmMgGdshdwy]?\\b",relevance:0},n]};return{name:"Nginx config",aliases:["nginxconf"],contains:[t.HASH_COMMENT_MODE,{beginKeywords:"upstream location",end:/;|\{/,contains:o.contains,keywords:{section:"upstream location"}},{className:"section",begin:e.concat(t.UNDERSCORE_IDENT_RE+e.lookahead(/\s+\{/)),relevance:0},{begin:e.lookahead(t.UNDERSCORE_IDENT_RE+"\\s"),end:";|\\{",contains:[{className:"attribute",begin:t.UNDERSCORE_IDENT_RE,starts:o}],relevance:0}],illegal:"[^\\s\\}\\{]"}})),J.registerLanguage("objectivec",(function(t){const n=/[a-zA-Z@][a-zA-Z0-9_]*/,l={$pattern:n,keyword:["@interface","@class","@protocol","@implementation"]};return{name:"Objective-C",aliases:["mm","objc","obj-c","obj-c++","objective-c++"],keywords:{"variable.language":["this","super"],$pattern:n,keyword:["while","export","sizeof","typedef","const","struct","for","union","volatile","static","mutable","if","do","return","goto","enum","else","break","extern","asm","case","default","register","explicit","typename","switch","continue","inline","readonly","assign","readwrite","self","@synchronized","id","typeof","nonatomic","IBOutlet","IBAction","strong","weak","copy","in","out","inout","bycopy","byref","oneway","__strong","__weak","__block","__autoreleasing","@private","@protected","@public","@try","@property","@end","@throw","@catch","@finally","@autoreleasepool","@synthesize","@dynamic","@selector","@optional","@required","@encode","@package","@import","@defs","@compatibility_alias","__bridge","__bridge_transfer","__bridge_retained","__bridge_retain","__covariant","__contravariant","__kindof","_Nonnull","_Nullable","_Null_unspecified","__FUNCTION__","__PRETTY_FUNCTION__","__attribute__","getter","setter","retain","unsafe_unretained","nonnull","nullable","null_unspecified","null_resettable","class","instancetype","NS_DESIGNATED_INITIALIZER","NS_UNAVAILABLE","NS_REQUIRES_SUPER","NS_RETURNS_INNER_POINTER","NS_INLINE","NS_AVAILABLE","NS_DEPRECATED","NS_ENUM","NS_OPTIONS","NS_SWIFT_UNAVAILABLE","NS_ASSUME_NONNULL_BEGIN","NS_ASSUME_NONNULL_END","NS_REFINED_FOR_SWIFT","NS_SWIFT_NAME","NS_SWIFT_NOTHROW","NS_DURING","NS_HANDLER","NS_ENDHANDLER","NS_VALUERETURN","NS_VOIDRETURN"],literal:["false","true","FALSE","TRUE","nil","YES","NO","NULL"],built_in:["dispatch_once_t","dispatch_queue_t","dispatch_sync","dispatch_async","dispatch_once"],type:["int","float","char","unsigned","signed","short","long","double","wchar_t","unichar","void","bool","BOOL","id|0","_Bool"]},illegal:"/,end:/$/,illegal:"\\n"},t.C_LINE_COMMENT_MODE,t.C_BLOCK_COMMENT_MODE]},{className:"class",begin:"("+l.keyword.join("|")+")\\b",end:/(\{|$)/,excludeEnd:!0,keywords:l,contains:[t.UNDERSCORE_TITLE_MODE]},{begin:"\\."+t.UNDERSCORE_IDENT_RE,relevance:0}]}})),J.registerLanguage("perl",(function(t){const e=t.regex,r=/[dualxmsipngr]{0,12}/,o={$pattern:/[\w.]+/,keyword:["abs","accept","alarm","and","atan2","bind","binmode","bless","break","caller","chdir","chmod","chomp","chop","chown","chr","chroot","close","closedir","connect","continue","cos","crypt","dbmclose","dbmopen","defined","delete","die","do","dump","each","else","elsif","endgrent","endhostent","endnetent","endprotoent","endpwent","endservent","eof","eval","exec","exists","exit","exp","fcntl","fileno","flock","for","foreach","fork","format","formline","getc","getgrent","getgrgid","getgrnam","gethostbyaddr","gethostbyname","gethostent","getlogin","getnetbyaddr","getnetbyname","getnetent","getpeername","getpgrp","getpriority","getprotobyname","getprotobynumber","getprotoent","getpwent","getpwnam","getpwuid","getservbyname","getservbyport","getservent","getsockname","getsockopt","given","glob","gmtime","goto","grep","gt","hex","if","index","int","ioctl","join","keys","kill","last","lc","lcfirst","length","link","listen","local","localtime","log","lstat","lt","ma","map","mkdir","msgctl","msgget","msgrcv","msgsnd","my","ne","next","no","not","oct","open","opendir","or","ord","our","pack","package","pipe","pop","pos","print","printf","prototype","push","q|0","qq","quotemeta","qw","qx","rand","read","readdir","readline","readlink","readpipe","recv","redo","ref","rename","require","reset","return","reverse","rewinddir","rindex","rmdir","say","scalar","seek","seekdir","select","semctl","semget","semop","send","setgrent","sethostent","setnetent","setpgrp","setpriority","setprotoent","setpwent","setservent","setsockopt","shift","shmctl","shmget","shmread","shmwrite","shutdown","sin","sleep","socket","socketpair","sort","splice","split","sprintf","sqrt","srand","stat","state","study","sub","substr","symlink","syscall","sysopen","sysread","sysseek","system","syswrite","tell","telldir","tie","tied","time","times","tr","truncate","uc","ucfirst","umask","undef","unless","unlink","unpack","unshift","untie","until","use","utime","values","vec","wait","waitpid","wantarray","warn","when","while","write","x|0","xor","y|0"].join(" ")},a={className:"subst",begin:"[$@]\\{",end:"\\}",keywords:o},s={begin:/->\{/,end:/\}/},i={variants:[{begin:/\$\d/},{begin:e.concat(/[$%@](\^\w\b|#\w+(::\w+)*|\{\w+\}|\w+(::\w*)*)/,"(?![A-Za-z])(?![@$%])")},{begin:/[$%@][^\s\w{]/,relevance:0}]},l=[t.BACKSLASH_ESCAPE,a,i],u=[/!/,/\//,/\|/,/\?/,/'/,/"/,/#/],c=(f,b,A="\\1")=>{const y="\\1"===A?A:e.concat(A,b);return e.concat(e.concat("(?:",f,")"),b,/(?:\\.|[^\\\/])*?/,y,/(?:\\.|[^\\\/])*?/,A,r)},p=(f,b,A)=>e.concat(e.concat("(?:",f,")"),b,/(?:\\.|[^\\\/])*?/,A,r),d=[i,t.HASH_COMMENT_MODE,t.COMMENT(/^=\w/,/=cut/,{endsWithParent:!0}),s,{className:"string",contains:l,variants:[{begin:"q[qwxr]?\\s*\\(",end:"\\)",relevance:5},{begin:"q[qwxr]?\\s*\\[",end:"\\]",relevance:5},{begin:"q[qwxr]?\\s*\\{",end:"\\}",relevance:5},{begin:"q[qwxr]?\\s*\\|",end:"\\|",relevance:5},{begin:"q[qwxr]?\\s*<",end:">",relevance:5},{begin:"qw\\s+q",end:"q",relevance:5},{begin:"'",end:"'",contains:[t.BACKSLASH_ESCAPE]},{begin:'"',end:'"'},{begin:"`",end:"`",contains:[t.BACKSLASH_ESCAPE]},{begin:/\{\w+\}/,relevance:0},{begin:"-?\\w+\\s*=>",relevance:0}]},{className:"number",begin:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",relevance:0},{begin:"(\\/\\/|"+t.RE_STARTERS_RE+"|\\b(split|return|print|reverse|grep)\\b)\\s*",keywords:"split return print reverse grep",relevance:0,contains:[t.HASH_COMMENT_MODE,{className:"regexp",variants:[{begin:c("s|tr|y",e.either(...u,{capture:!0}))},{begin:c("s|tr|y","\\(","\\)")},{begin:c("s|tr|y","\\[","\\]")},{begin:c("s|tr|y","\\{","\\}")}],relevance:2},{className:"regexp",variants:[{begin:/(m|qr)\/\//,relevance:0},{begin:p("(?:m|qr)?",/\//,/\//)},{begin:p("m|qr",e.either(...u,{capture:!0}),/\1/)},{begin:p("m|qr",/\(/,/\)/)},{begin:p("m|qr",/\[/,/\]/)},{begin:p("m|qr",/\{/,/\}/)}]}]},{className:"function",beginKeywords:"sub",end:"(\\s*\\(.*?\\))?[;{]",excludeEnd:!0,relevance:5,contains:[t.TITLE_MODE]},{begin:"-\\w\\b",relevance:0},{begin:"^__DATA__$",end:"^__END__$",subLanguage:"mojolicious",contains:[{begin:"^@@.*",end:"$",className:"comment"}]}];return a.contains=d,s.contains=d,{name:"Perl",aliases:["pl","pm"],keywords:o,contains:d}})),J.registerLanguage("pgsql",(function(t){const e=t.COMMENT("--","$"),r="\\$([a-zA-Z_]?|[a-zA-Z_][a-zA-Z_0-9]*)\\$",l="BIGINT INT8 BIGSERIAL SERIAL8 BIT VARYING VARBIT BOOLEAN BOOL BOX BYTEA CHARACTER CHAR VARCHAR CIDR CIRCLE DATE DOUBLE PRECISION FLOAT8 FLOAT INET INTEGER INT INT4 INTERVAL JSON JSONB LINE LSEG|10 MACADDR MACADDR8 MONEY NUMERIC DEC DECIMAL PATH POINT POLYGON REAL FLOAT4 SMALLINT INT2 SMALLSERIAL|10 SERIAL2|10 SERIAL|10 SERIAL4|10 TEXT TIME ZONE TIMETZ|10 TIMESTAMP TIMESTAMPTZ|10 TSQUERY|10 TSVECTOR|10 TXID_SNAPSHOT|10 UUID XML NATIONAL NCHAR INT4RANGE|10 INT8RANGE|10 NUMRANGE|10 TSRANGE|10 TSTZRANGE|10 DATERANGE|10 ANYELEMENT ANYARRAY ANYNONARRAY ANYENUM ANYRANGE CSTRING INTERNAL RECORD PG_DDL_COMMAND VOID UNKNOWN OPAQUE REFCURSOR NAME OID REGPROC|10 REGPROCEDURE|10 REGOPER|10 REGOPERATOR|10 REGCLASS|10 REGTYPE|10 REGROLE|10 REGNAMESPACE|10 REGCONFIG|10 REGDICTIONARY|10 ",u=l.trim().split(" ").map((function(A){return A.split("|")[0]})).join("|"),b="ARRAY_AGG AVG BIT_AND BIT_OR BOOL_AND BOOL_OR COUNT EVERY JSON_AGG JSONB_AGG JSON_OBJECT_AGG JSONB_OBJECT_AGG MAX MIN MODE STRING_AGG SUM XMLAGG CORR COVAR_POP COVAR_SAMP REGR_AVGX REGR_AVGY REGR_COUNT REGR_INTERCEPT REGR_R2 REGR_SLOPE REGR_SXX REGR_SXY REGR_SYY STDDEV STDDEV_POP STDDEV_SAMP VARIANCE VAR_POP VAR_SAMP PERCENTILE_CONT PERCENTILE_DISC ROW_NUMBER RANK DENSE_RANK PERCENT_RANK CUME_DIST NTILE LAG LEAD FIRST_VALUE LAST_VALUE NTH_VALUE NUM_NONNULLS NUM_NULLS ABS CBRT CEIL CEILING DEGREES DIV EXP FLOOR LN LOG MOD PI POWER RADIANS ROUND SCALE SIGN SQRT TRUNC WIDTH_BUCKET RANDOM SETSEED ACOS ACOSD ASIN ASIND ATAN ATAND ATAN2 ATAN2D COS COSD COT COTD SIN SIND TAN TAND BIT_LENGTH CHAR_LENGTH CHARACTER_LENGTH LOWER OCTET_LENGTH OVERLAY POSITION SUBSTRING TREAT TRIM UPPER ASCII BTRIM CHR CONCAT CONCAT_WS CONVERT CONVERT_FROM CONVERT_TO DECODE ENCODE INITCAP LEFT LENGTH LPAD LTRIM MD5 PARSE_IDENT PG_CLIENT_ENCODING QUOTE_IDENT|10 QUOTE_LITERAL|10 QUOTE_NULLABLE|10 REGEXP_MATCH REGEXP_MATCHES REGEXP_REPLACE REGEXP_SPLIT_TO_ARRAY REGEXP_SPLIT_TO_TABLE REPEAT REPLACE REVERSE RIGHT RPAD RTRIM SPLIT_PART STRPOS SUBSTR TO_ASCII TO_HEX TRANSLATE OCTET_LENGTH GET_BIT GET_BYTE SET_BIT SET_BYTE TO_CHAR TO_DATE TO_NUMBER TO_TIMESTAMP AGE CLOCK_TIMESTAMP|10 DATE_PART DATE_TRUNC ISFINITE JUSTIFY_DAYS JUSTIFY_HOURS JUSTIFY_INTERVAL MAKE_DATE MAKE_INTERVAL|10 MAKE_TIME MAKE_TIMESTAMP|10 MAKE_TIMESTAMPTZ|10 NOW STATEMENT_TIMESTAMP|10 TIMEOFDAY TRANSACTION_TIMESTAMP|10 ENUM_FIRST ENUM_LAST ENUM_RANGE AREA CENTER DIAMETER HEIGHT ISCLOSED ISOPEN NPOINTS PCLOSE POPEN RADIUS WIDTH BOX BOUND_BOX CIRCLE LINE LSEG PATH POLYGON ABBREV BROADCAST HOST HOSTMASK MASKLEN NETMASK NETWORK SET_MASKLEN TEXT INET_SAME_FAMILY INET_MERGE MACADDR8_SET7BIT ARRAY_TO_TSVECTOR GET_CURRENT_TS_CONFIG NUMNODE PLAINTO_TSQUERY PHRASETO_TSQUERY WEBSEARCH_TO_TSQUERY QUERYTREE SETWEIGHT STRIP TO_TSQUERY TO_TSVECTOR JSON_TO_TSVECTOR JSONB_TO_TSVECTOR TS_DELETE TS_FILTER TS_HEADLINE TS_RANK TS_RANK_CD TS_REWRITE TSQUERY_PHRASE TSVECTOR_TO_ARRAY TSVECTOR_UPDATE_TRIGGER TSVECTOR_UPDATE_TRIGGER_COLUMN XMLCOMMENT XMLCONCAT XMLELEMENT XMLFOREST XMLPI XMLROOT XMLEXISTS XML_IS_WELL_FORMED XML_IS_WELL_FORMED_DOCUMENT XML_IS_WELL_FORMED_CONTENT XPATH XPATH_EXISTS XMLTABLE XMLNAMESPACES TABLE_TO_XML TABLE_TO_XMLSCHEMA TABLE_TO_XML_AND_XMLSCHEMA QUERY_TO_XML QUERY_TO_XMLSCHEMA QUERY_TO_XML_AND_XMLSCHEMA CURSOR_TO_XML CURSOR_TO_XMLSCHEMA SCHEMA_TO_XML SCHEMA_TO_XMLSCHEMA SCHEMA_TO_XML_AND_XMLSCHEMA DATABASE_TO_XML DATABASE_TO_XMLSCHEMA DATABASE_TO_XML_AND_XMLSCHEMA XMLATTRIBUTES TO_JSON TO_JSONB ARRAY_TO_JSON ROW_TO_JSON JSON_BUILD_ARRAY JSONB_BUILD_ARRAY JSON_BUILD_OBJECT JSONB_BUILD_OBJECT JSON_OBJECT JSONB_OBJECT JSON_ARRAY_LENGTH JSONB_ARRAY_LENGTH JSON_EACH JSONB_EACH JSON_EACH_TEXT JSONB_EACH_TEXT JSON_EXTRACT_PATH JSONB_EXTRACT_PATH JSON_OBJECT_KEYS JSONB_OBJECT_KEYS JSON_POPULATE_RECORD JSONB_POPULATE_RECORD JSON_POPULATE_RECORDSET JSONB_POPULATE_RECORDSET JSON_ARRAY_ELEMENTS JSONB_ARRAY_ELEMENTS JSON_ARRAY_ELEMENTS_TEXT JSONB_ARRAY_ELEMENTS_TEXT JSON_TYPEOF JSONB_TYPEOF JSON_TO_RECORD JSONB_TO_RECORD JSON_TO_RECORDSET JSONB_TO_RECORDSET JSON_STRIP_NULLS JSONB_STRIP_NULLS JSONB_SET JSONB_INSERT JSONB_PRETTY CURRVAL LASTVAL NEXTVAL SETVAL COALESCE NULLIF GREATEST LEAST ARRAY_APPEND ARRAY_CAT ARRAY_NDIMS ARRAY_DIMS ARRAY_FILL ARRAY_LENGTH ARRAY_LOWER ARRAY_POSITION ARRAY_POSITIONS ARRAY_PREPEND ARRAY_REMOVE ARRAY_REPLACE ARRAY_TO_STRING ARRAY_UPPER CARDINALITY STRING_TO_ARRAY UNNEST ISEMPTY LOWER_INC UPPER_INC LOWER_INF UPPER_INF RANGE_MERGE GENERATE_SERIES GENERATE_SUBSCRIPTS CURRENT_DATABASE CURRENT_QUERY CURRENT_SCHEMA|10 CURRENT_SCHEMAS|10 INET_CLIENT_ADDR INET_CLIENT_PORT INET_SERVER_ADDR INET_SERVER_PORT ROW_SECURITY_ACTIVE FORMAT_TYPE TO_REGCLASS TO_REGPROC TO_REGPROCEDURE TO_REGOPER TO_REGOPERATOR TO_REGTYPE TO_REGNAMESPACE TO_REGROLE COL_DESCRIPTION OBJ_DESCRIPTION SHOBJ_DESCRIPTION TXID_CURRENT TXID_CURRENT_IF_ASSIGNED TXID_CURRENT_SNAPSHOT TXID_SNAPSHOT_XIP TXID_SNAPSHOT_XMAX TXID_SNAPSHOT_XMIN TXID_VISIBLE_IN_SNAPSHOT TXID_STATUS CURRENT_SETTING SET_CONFIG BRIN_SUMMARIZE_NEW_VALUES BRIN_SUMMARIZE_RANGE BRIN_DESUMMARIZE_RANGE GIN_CLEAN_PENDING_LIST SUPPRESS_REDUNDANT_UPDATES_TRIGGER LO_FROM_BYTEA LO_PUT LO_GET LO_CREAT LO_CREATE LO_UNLINK LO_IMPORT LO_EXPORT LOREAD LOWRITE GROUPING CAST ".trim().split(" ").map((function(A){return A.split("|")[0]})).join("|");return{name:"PostgreSQL",aliases:["postgres","postgresql"],supersetOf:"sql",case_insensitive:!0,keywords:{keyword:"ABORT ALTER ANALYZE BEGIN CALL CHECKPOINT|10 CLOSE CLUSTER COMMENT COMMIT COPY CREATE DEALLOCATE DECLARE DELETE DISCARD DO DROP END EXECUTE EXPLAIN FETCH GRANT IMPORT INSERT LISTEN LOAD LOCK MOVE NOTIFY PREPARE REASSIGN|10 REFRESH REINDEX RELEASE RESET REVOKE ROLLBACK SAVEPOINT SECURITY SELECT SET SHOW START TRUNCATE UNLISTEN|10 UPDATE VACUUM|10 VALUES AGGREGATE COLLATION CONVERSION|10 DATABASE DEFAULT PRIVILEGES DOMAIN TRIGGER EXTENSION FOREIGN WRAPPER|10 TABLE FUNCTION GROUP LANGUAGE LARGE OBJECT MATERIALIZED VIEW OPERATOR CLASS FAMILY POLICY PUBLICATION|10 ROLE RULE SCHEMA SEQUENCE SERVER STATISTICS SUBSCRIPTION SYSTEM TABLESPACE CONFIGURATION DICTIONARY PARSER TEMPLATE TYPE USER MAPPING PREPARED ACCESS METHOD CAST AS TRANSFORM TRANSACTION OWNED TO INTO SESSION AUTHORIZATION INDEX PROCEDURE ASSERTION ALL ANALYSE AND ANY ARRAY ASC ASYMMETRIC|10 BOTH CASE CHECK COLLATE COLUMN CONCURRENTLY|10 CONSTRAINT CROSS DEFERRABLE RANGE DESC DISTINCT ELSE EXCEPT FOR FREEZE|10 FROM FULL HAVING ILIKE IN INITIALLY INNER INTERSECT IS ISNULL JOIN LATERAL LEADING LIKE LIMIT NATURAL NOT NOTNULL NULL OFFSET ON ONLY OR ORDER OUTER OVERLAPS PLACING PRIMARY REFERENCES RETURNING SIMILAR SOME SYMMETRIC TABLESAMPLE THEN TRAILING UNION UNIQUE USING VARIADIC|10 VERBOSE WHEN WHERE WINDOW WITH BY RETURNS INOUT OUT SETOF|10 IF STRICT CURRENT CONTINUE OWNER LOCATION OVER PARTITION WITHIN BETWEEN ESCAPE EXTERNAL INVOKER DEFINER WORK RENAME VERSION CONNECTION CONNECT TABLES TEMP TEMPORARY FUNCTIONS SEQUENCES TYPES SCHEMAS OPTION CASCADE RESTRICT ADD ADMIN EXISTS VALID VALIDATE ENABLE DISABLE REPLICA|10 ALWAYS PASSING COLUMNS PATH REF VALUE OVERRIDING IMMUTABLE STABLE VOLATILE BEFORE AFTER EACH ROW PROCEDURAL ROUTINE NO HANDLER VALIDATOR OPTIONS STORAGE OIDS|10 WITHOUT INHERIT DEPENDS CALLED INPUT LEAKPROOF|10 COST ROWS NOWAIT SEARCH UNTIL ENCRYPTED|10 PASSWORD CONFLICT|10 INSTEAD INHERITS CHARACTERISTICS WRITE CURSOR ALSO STATEMENT SHARE EXCLUSIVE INLINE ISOLATION REPEATABLE READ COMMITTED SERIALIZABLE UNCOMMITTED LOCAL GLOBAL SQL PROCEDURES RECURSIVE SNAPSHOT ROLLUP CUBE TRUSTED|10 INCLUDE FOLLOWING PRECEDING UNBOUNDED RANGE GROUPS UNENCRYPTED|10 SYSID FORMAT DELIMITER HEADER QUOTE ENCODING FILTER OFF FORCE_QUOTE FORCE_NOT_NULL FORCE_NULL COSTS BUFFERS TIMING SUMMARY DISABLE_PAGE_SKIPPING RESTART CYCLE GENERATED IDENTITY DEFERRED IMMEDIATE LEVEL LOGGED UNLOGGED OF NOTHING NONE EXCLUDE ATTRIBUTE USAGE ROUTINES TRUE FALSE NAN INFINITY ALIAS BEGIN CONSTANT DECLARE END EXCEPTION RETURN PERFORM|10 RAISE GET DIAGNOSTICS STACKED|10 FOREACH LOOP ELSIF EXIT WHILE REVERSE SLICE DEBUG LOG INFO NOTICE WARNING ASSERT OPEN SUPERUSER NOSUPERUSER CREATEDB NOCREATEDB CREATEROLE NOCREATEROLE INHERIT NOINHERIT LOGIN NOLOGIN REPLICATION NOREPLICATION BYPASSRLS NOBYPASSRLS ",built_in:"CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER CURRENT_CATALOG|10 CURRENT_DATE LOCALTIME LOCALTIMESTAMP CURRENT_ROLE|10 CURRENT_SCHEMA|10 SESSION_USER PUBLIC FOUND NEW OLD TG_NAME|10 TG_WHEN|10 TG_LEVEL|10 TG_OP|10 TG_RELID|10 TG_RELNAME|10 TG_TABLE_NAME|10 TG_TABLE_SCHEMA|10 TG_NARGS|10 TG_ARGV|10 TG_EVENT|10 TG_TAG|10 ROW_COUNT RESULT_OID|10 PG_CONTEXT|10 RETURNED_SQLSTATE COLUMN_NAME CONSTRAINT_NAME PG_DATATYPE_NAME|10 MESSAGE_TEXT TABLE_NAME SCHEMA_NAME PG_EXCEPTION_DETAIL|10 PG_EXCEPTION_HINT|10 PG_EXCEPTION_CONTEXT|10 SQLSTATE SQLERRM|10 SUCCESSFUL_COMPLETION WARNING DYNAMIC_RESULT_SETS_RETURNED IMPLICIT_ZERO_BIT_PADDING NULL_VALUE_ELIMINATED_IN_SET_FUNCTION PRIVILEGE_NOT_GRANTED PRIVILEGE_NOT_REVOKED STRING_DATA_RIGHT_TRUNCATION DEPRECATED_FEATURE NO_DATA NO_ADDITIONAL_DYNAMIC_RESULT_SETS_RETURNED SQL_STATEMENT_NOT_YET_COMPLETE CONNECTION_EXCEPTION CONNECTION_DOES_NOT_EXIST CONNECTION_FAILURE SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION SQLSERVER_REJECTED_ESTABLISHMENT_OF_SQLCONNECTION TRANSACTION_RESOLUTION_UNKNOWN PROTOCOL_VIOLATION TRIGGERED_ACTION_EXCEPTION FEATURE_NOT_SUPPORTED INVALID_TRANSACTION_INITIATION LOCATOR_EXCEPTION INVALID_LOCATOR_SPECIFICATION INVALID_GRANTOR INVALID_GRANT_OPERATION INVALID_ROLE_SPECIFICATION DIAGNOSTICS_EXCEPTION STACKED_DIAGNOSTICS_ACCESSED_WITHOUT_ACTIVE_HANDLER CASE_NOT_FOUND CARDINALITY_VIOLATION DATA_EXCEPTION ARRAY_SUBSCRIPT_ERROR CHARACTER_NOT_IN_REPERTOIRE DATETIME_FIELD_OVERFLOW DIVISION_BY_ZERO ERROR_IN_ASSIGNMENT ESCAPE_CHARACTER_CONFLICT INDICATOR_OVERFLOW INTERVAL_FIELD_OVERFLOW INVALID_ARGUMENT_FOR_LOGARITHM INVALID_ARGUMENT_FOR_NTILE_FUNCTION INVALID_ARGUMENT_FOR_NTH_VALUE_FUNCTION INVALID_ARGUMENT_FOR_POWER_FUNCTION INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION INVALID_CHARACTER_VALUE_FOR_CAST INVALID_DATETIME_FORMAT INVALID_ESCAPE_CHARACTER INVALID_ESCAPE_OCTET INVALID_ESCAPE_SEQUENCE NONSTANDARD_USE_OF_ESCAPE_CHARACTER INVALID_INDICATOR_PARAMETER_VALUE INVALID_PARAMETER_VALUE INVALID_REGULAR_EXPRESSION INVALID_ROW_COUNT_IN_LIMIT_CLAUSE INVALID_ROW_COUNT_IN_RESULT_OFFSET_CLAUSE INVALID_TABLESAMPLE_ARGUMENT INVALID_TABLESAMPLE_REPEAT INVALID_TIME_ZONE_DISPLACEMENT_VALUE INVALID_USE_OF_ESCAPE_CHARACTER MOST_SPECIFIC_TYPE_MISMATCH NULL_VALUE_NOT_ALLOWED NULL_VALUE_NO_INDICATOR_PARAMETER NUMERIC_VALUE_OUT_OF_RANGE SEQUENCE_GENERATOR_LIMIT_EXCEEDED STRING_DATA_LENGTH_MISMATCH STRING_DATA_RIGHT_TRUNCATION SUBSTRING_ERROR TRIM_ERROR UNTERMINATED_C_STRING ZERO_LENGTH_CHARACTER_STRING FLOATING_POINT_EXCEPTION INVALID_TEXT_REPRESENTATION INVALID_BINARY_REPRESENTATION BAD_COPY_FILE_FORMAT UNTRANSLATABLE_CHARACTER NOT_AN_XML_DOCUMENT INVALID_XML_DOCUMENT INVALID_XML_CONTENT INVALID_XML_COMMENT INVALID_XML_PROCESSING_INSTRUCTION INTEGRITY_CONSTRAINT_VIOLATION RESTRICT_VIOLATION NOT_NULL_VIOLATION FOREIGN_KEY_VIOLATION UNIQUE_VIOLATION CHECK_VIOLATION EXCLUSION_VIOLATION INVALID_CURSOR_STATE INVALID_TRANSACTION_STATE ACTIVE_SQL_TRANSACTION BRANCH_TRANSACTION_ALREADY_ACTIVE HELD_CURSOR_REQUIRES_SAME_ISOLATION_LEVEL INAPPROPRIATE_ACCESS_MODE_FOR_BRANCH_TRANSACTION INAPPROPRIATE_ISOLATION_LEVEL_FOR_BRANCH_TRANSACTION NO_ACTIVE_SQL_TRANSACTION_FOR_BRANCH_TRANSACTION READ_ONLY_SQL_TRANSACTION SCHEMA_AND_DATA_STATEMENT_MIXING_NOT_SUPPORTED NO_ACTIVE_SQL_TRANSACTION IN_FAILED_SQL_TRANSACTION IDLE_IN_TRANSACTION_SESSION_TIMEOUT INVALID_SQL_STATEMENT_NAME TRIGGERED_DATA_CHANGE_VIOLATION INVALID_AUTHORIZATION_SPECIFICATION INVALID_PASSWORD DEPENDENT_PRIVILEGE_DESCRIPTORS_STILL_EXIST DEPENDENT_OBJECTS_STILL_EXIST INVALID_TRANSACTION_TERMINATION SQL_ROUTINE_EXCEPTION FUNCTION_EXECUTED_NO_RETURN_STATEMENT MODIFYING_SQL_DATA_NOT_PERMITTED PROHIBITED_SQL_STATEMENT_ATTEMPTED READING_SQL_DATA_NOT_PERMITTED INVALID_CURSOR_NAME EXTERNAL_ROUTINE_EXCEPTION CONTAINING_SQL_NOT_PERMITTED MODIFYING_SQL_DATA_NOT_PERMITTED PROHIBITED_SQL_STATEMENT_ATTEMPTED READING_SQL_DATA_NOT_PERMITTED EXTERNAL_ROUTINE_INVOCATION_EXCEPTION INVALID_SQLSTATE_RETURNED NULL_VALUE_NOT_ALLOWED TRIGGER_PROTOCOL_VIOLATED SRF_PROTOCOL_VIOLATED EVENT_TRIGGER_PROTOCOL_VIOLATED SAVEPOINT_EXCEPTION INVALID_SAVEPOINT_SPECIFICATION INVALID_CATALOG_NAME INVALID_SCHEMA_NAME TRANSACTION_ROLLBACK TRANSACTION_INTEGRITY_CONSTRAINT_VIOLATION SERIALIZATION_FAILURE STATEMENT_COMPLETION_UNKNOWN DEADLOCK_DETECTED SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION SYNTAX_ERROR INSUFFICIENT_PRIVILEGE CANNOT_COERCE GROUPING_ERROR WINDOWING_ERROR INVALID_RECURSION INVALID_FOREIGN_KEY INVALID_NAME NAME_TOO_LONG RESERVED_NAME DATATYPE_MISMATCH INDETERMINATE_DATATYPE COLLATION_MISMATCH INDETERMINATE_COLLATION WRONG_OBJECT_TYPE GENERATED_ALWAYS UNDEFINED_COLUMN UNDEFINED_FUNCTION UNDEFINED_TABLE UNDEFINED_PARAMETER UNDEFINED_OBJECT DUPLICATE_COLUMN DUPLICATE_CURSOR DUPLICATE_DATABASE DUPLICATE_FUNCTION DUPLICATE_PREPARED_STATEMENT DUPLICATE_SCHEMA DUPLICATE_TABLE DUPLICATE_ALIAS DUPLICATE_OBJECT AMBIGUOUS_COLUMN AMBIGUOUS_FUNCTION AMBIGUOUS_PARAMETER AMBIGUOUS_ALIAS INVALID_COLUMN_REFERENCE INVALID_COLUMN_DEFINITION INVALID_CURSOR_DEFINITION INVALID_DATABASE_DEFINITION INVALID_FUNCTION_DEFINITION INVALID_PREPARED_STATEMENT_DEFINITION INVALID_SCHEMA_DEFINITION INVALID_TABLE_DEFINITION INVALID_OBJECT_DEFINITION WITH_CHECK_OPTION_VIOLATION INSUFFICIENT_RESOURCES DISK_FULL OUT_OF_MEMORY TOO_MANY_CONNECTIONS CONFIGURATION_LIMIT_EXCEEDED PROGRAM_LIMIT_EXCEEDED STATEMENT_TOO_COMPLEX TOO_MANY_COLUMNS TOO_MANY_ARGUMENTS OBJECT_NOT_IN_PREREQUISITE_STATE OBJECT_IN_USE CANT_CHANGE_RUNTIME_PARAM LOCK_NOT_AVAILABLE OPERATOR_INTERVENTION QUERY_CANCELED ADMIN_SHUTDOWN CRASH_SHUTDOWN CANNOT_CONNECT_NOW DATABASE_DROPPED SYSTEM_ERROR IO_ERROR UNDEFINED_FILE DUPLICATE_FILE SNAPSHOT_TOO_OLD CONFIG_FILE_ERROR LOCK_FILE_EXISTS FDW_ERROR FDW_COLUMN_NAME_NOT_FOUND FDW_DYNAMIC_PARAMETER_VALUE_NEEDED FDW_FUNCTION_SEQUENCE_ERROR FDW_INCONSISTENT_DESCRIPTOR_INFORMATION FDW_INVALID_ATTRIBUTE_VALUE FDW_INVALID_COLUMN_NAME FDW_INVALID_COLUMN_NUMBER FDW_INVALID_DATA_TYPE FDW_INVALID_DATA_TYPE_DESCRIPTORS FDW_INVALID_DESCRIPTOR_FIELD_IDENTIFIER FDW_INVALID_HANDLE FDW_INVALID_OPTION_INDEX FDW_INVALID_OPTION_NAME FDW_INVALID_STRING_LENGTH_OR_BUFFER_LENGTH FDW_INVALID_STRING_FORMAT FDW_INVALID_USE_OF_NULL_POINTER FDW_TOO_MANY_HANDLES FDW_OUT_OF_MEMORY FDW_NO_SCHEMAS FDW_OPTION_NAME_NOT_FOUND FDW_REPLY_HANDLE FDW_SCHEMA_NOT_FOUND FDW_TABLE_NOT_FOUND FDW_UNABLE_TO_CREATE_EXECUTION FDW_UNABLE_TO_CREATE_REPLY FDW_UNABLE_TO_ESTABLISH_CONNECTION PLPGSQL_ERROR RAISE_EXCEPTION NO_DATA_FOUND TOO_MANY_ROWS ASSERT_FAILURE INTERNAL_ERROR DATA_CORRUPTED INDEX_CORRUPTED "},illegal:/:==|\W\s*\(\*|(^|\s)\$[a-z]|\{\{|[a-z]:\s*$|\.\.\.|TO:|DO:/,contains:[{className:"keyword",variants:[{begin:/\bTEXT\s*SEARCH\b/},{begin:/\b(PRIMARY|FOREIGN|FOR(\s+NO)?)\s+KEY\b/},{begin:/\bPARALLEL\s+(UNSAFE|RESTRICTED|SAFE)\b/},{begin:/\bSTORAGE\s+(PLAIN|EXTERNAL|EXTENDED|MAIN)\b/},{begin:/\bMATCH\s+(FULL|PARTIAL|SIMPLE)\b/},{begin:/\bNULLS\s+(FIRST|LAST)\b/},{begin:/\bEVENT\s+TRIGGER\b/},{begin:/\b(MAPPING|OR)\s+REPLACE\b/},{begin:/\b(FROM|TO)\s+(PROGRAM|STDIN|STDOUT)\b/},{begin:/\b(SHARE|EXCLUSIVE)\s+MODE\b/},{begin:/\b(LEFT|RIGHT)\s+(OUTER\s+)?JOIN\b/},{begin:/\b(FETCH|MOVE)\s+(NEXT|PRIOR|FIRST|LAST|ABSOLUTE|RELATIVE|FORWARD|BACKWARD)\b/},{begin:/\bPRESERVE\s+ROWS\b/},{begin:/\bDISCARD\s+PLANS\b/},{begin:/\bREFERENCING\s+(OLD|NEW)\b/},{begin:/\bSKIP\s+LOCKED\b/},{begin:/\bGROUPING\s+SETS\b/},{begin:/\b(BINARY|INSENSITIVE|SCROLL|NO\s+SCROLL)\s+(CURSOR|FOR)\b/},{begin:/\b(WITH|WITHOUT)\s+HOLD\b/},{begin:/\bWITH\s+(CASCADED|LOCAL)\s+CHECK\s+OPTION\b/},{begin:/\bEXCLUDE\s+(TIES|NO\s+OTHERS)\b/},{begin:/\bFORMAT\s+(TEXT|XML|JSON|YAML)\b/},{begin:/\bSET\s+((SESSION|LOCAL)\s+)?NAMES\b/},{begin:/\bIS\s+(NOT\s+)?UNKNOWN\b/},{begin:/\bSECURITY\s+LABEL\b/},{begin:/\bSTANDALONE\s+(YES|NO|NO\s+VALUE)\b/},{begin:/\bWITH\s+(NO\s+)?DATA\b/},{begin:/\b(FOREIGN|SET)\s+DATA\b/},{begin:/\bSET\s+(CATALOG|CONSTRAINTS)\b/},{begin:/\b(WITH|FOR)\s+ORDINALITY\b/},{begin:/\bIS\s+(NOT\s+)?DOCUMENT\b/},{begin:/\bXML\s+OPTION\s+(DOCUMENT|CONTENT)\b/},{begin:/\b(STRIP|PRESERVE)\s+WHITESPACE\b/},{begin:/\bNO\s+(ACTION|MAXVALUE|MINVALUE)\b/},{begin:/\bPARTITION\s+BY\s+(RANGE|LIST|HASH)\b/},{begin:/\bAT\s+TIME\s+ZONE\b/},{begin:/\bGRANTED\s+BY\b/},{begin:/\bRETURN\s+(QUERY|NEXT)\b/},{begin:/\b(ATTACH|DETACH)\s+PARTITION\b/},{begin:/\bFORCE\s+ROW\s+LEVEL\s+SECURITY\b/},{begin:/\b(INCLUDING|EXCLUDING)\s+(COMMENTS|CONSTRAINTS|DEFAULTS|IDENTITY|INDEXES|STATISTICS|STORAGE|ALL)\b/},{begin:/\bAS\s+(ASSIGNMENT|IMPLICIT|PERMISSIVE|RESTRICTIVE|ENUM|RANGE)\b/}]},{begin:/\b(FORMAT|FAMILY|VERSION)\s*\(/},{begin:/\bINCLUDE\s*\(/,keywords:"INCLUDE"},{begin:/\bRANGE(?!\s*(BETWEEN|UNBOUNDED|CURRENT|[-0-9]+))/},{begin:/\b(VERSION|OWNER|TEMPLATE|TABLESPACE|CONNECTION\s+LIMIT|PROCEDURE|RESTRICT|JOIN|PARSER|COPY|START|END|COLLATION|INPUT|ANALYZE|STORAGE|LIKE|DEFAULT|DELIMITER|ENCODING|COLUMN|CONSTRAINT|TABLE|SCHEMA)\s*=/},{begin:/\b(PG_\w+?|HAS_[A-Z_]+_PRIVILEGE)\b/,relevance:10},{begin:/\bEXTRACT\s*\(/,end:/\bFROM\b/,returnEnd:!0,keywords:{type:"CENTURY DAY DECADE DOW DOY EPOCH HOUR ISODOW ISOYEAR MICROSECONDS MILLENNIUM MILLISECONDS MINUTE MONTH QUARTER SECOND TIMEZONE TIMEZONE_HOUR TIMEZONE_MINUTE WEEK YEAR"}},{begin:/\b(XMLELEMENT|XMLPI)\s*\(\s*NAME/,keywords:{keyword:"NAME"}},{begin:/\b(XMLPARSE|XMLSERIALIZE)\s*\(\s*(DOCUMENT|CONTENT)/,keywords:{keyword:"DOCUMENT CONTENT"}},{beginKeywords:"CACHE INCREMENT MAXVALUE MINVALUE",end:t.C_NUMBER_RE,returnEnd:!0,keywords:"BY CACHE INCREMENT MAXVALUE MINVALUE"},{className:"type",begin:/\b(WITH|WITHOUT)\s+TIME\s+ZONE\b/},{className:"type",begin:/\bINTERVAL\s+(YEAR|MONTH|DAY|HOUR|MINUTE|SECOND)(\s+TO\s+(MONTH|HOUR|MINUTE|SECOND))?\b/},{begin:/\bRETURNS\s+(LANGUAGE_HANDLER|TRIGGER|EVENT_TRIGGER|FDW_HANDLER|INDEX_AM_HANDLER|TSM_HANDLER)\b/,keywords:{keyword:"RETURNS",type:"LANGUAGE_HANDLER TRIGGER EVENT_TRIGGER FDW_HANDLER INDEX_AM_HANDLER TSM_HANDLER"}},{begin:"\\b("+b+")\\s*\\("},{begin:"\\.("+u+")\\b"},{begin:"\\b("+u+")\\s+PATH\\b",keywords:{keyword:"PATH",type:l.replace("PATH ","")}},{className:"type",begin:"\\b("+u+")\\b"},{className:"string",begin:"'",end:"'",contains:[{begin:"''"}]},{className:"string",begin:"(e|E|u&|U&)'",end:"'",contains:[{begin:"\\\\."}],relevance:10},t.END_SAME_AS_BEGIN({begin:r,end:r,contains:[{subLanguage:["pgsql","perl","python","tcl","r","lua","java","php","ruby","bash","scheme","xml","json"],endsWithParent:!0}]}),{begin:'"',end:'"',contains:[{begin:'""'}]},t.C_NUMBER_MODE,t.C_BLOCK_COMMENT_MODE,e,{className:"meta",variants:[{begin:"%(ROW)?TYPE",relevance:10},{begin:"\\$\\d+"},{begin:"^#\\w",end:"$"}]},{className:"symbol",begin:"<<\\s*[a-zA-Z_][a-zA-Z_0-9$]*\\s*>>",relevance:10}]}})),J.registerLanguage("php",(function(t){const e=t.regex,n=/(?![A-Za-z0-9])(?![$])/,r=e.concat(/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/,n),o=e.concat(/(\\?[A-Z][a-z0-9_\x7f-\xff]+|\\?[A-Z]+(?=[A-Z][a-z0-9_\x7f-\xff])){1,}/,n),a={scope:"variable",match:"\\$+"+r},i={scope:"subst",variants:[{begin:/\$\w+/},{begin:/\{\$/,end:/\}/}]},l=t.inherit(t.APOS_STRING_MODE,{illegal:null}),d="[ \t\n]",f={scope:"string",variants:[t.inherit(t.QUOTE_STRING_MODE,{illegal:null,contains:t.QUOTE_STRING_MODE.contains.concat(i)}),l,{begin:/<<<[ \t]*(?:(\w+)|"(\w+)")\n/,end:/[ \t]*(\w+)\b/,contains:t.QUOTE_STRING_MODE.contains.concat(i),"on:begin":(K,O)=>{O.data._beginMatch=K[1]||K[2]},"on:end":(K,O)=>{O.data._beginMatch!==K[1]&&O.ignoreMatch()}},t.END_SAME_AS_BEGIN({begin:/<<<[ \t]*'(\w+)'\n/,end:/[ \t]*(\w+)\b/})]},b={scope:"number",variants:[{begin:"\\b0[bB][01]+(?:_[01]+)*\\b"},{begin:"\\b0[oO][0-7]+(?:_[0-7]+)*\\b"},{begin:"\\b0[xX][\\da-fA-F]+(?:_[\\da-fA-F]+)*\\b"},{begin:"(?:\\b\\d+(?:_\\d+)*(\\.(?:\\d+(?:_\\d+)*))?|\\B\\.\\d+)(?:[eE][+-]?\\d+)?"}],relevance:0},A=["false","null","true"],y=["__CLASS__","__DIR__","__FILE__","__FUNCTION__","__COMPILER_HALT_OFFSET__","__LINE__","__METHOD__","__NAMESPACE__","__TRAIT__","die","echo","exit","include","include_once","print","require","require_once","array","abstract","and","as","binary","bool","boolean","break","callable","case","catch","class","clone","const","continue","declare","default","do","double","else","elseif","empty","enddeclare","endfor","endforeach","endif","endswitch","endwhile","enum","eval","extends","final","finally","float","for","foreach","from","global","goto","if","implements","instanceof","insteadof","int","integer","interface","isset","iterable","list","match|0","mixed","new","never","object","or","private","protected","public","readonly","real","return","string","switch","throw","trait","try","unset","use","var","void","while","xor","yield"],h=["Error|0","AppendIterator","ArgumentCountError","ArithmeticError","ArrayIterator","ArrayObject","AssertionError","BadFunctionCallException","BadMethodCallException","CachingIterator","CallbackFilterIterator","CompileError","Countable","DirectoryIterator","DivisionByZeroError","DomainException","EmptyIterator","ErrorException","Exception","FilesystemIterator","FilterIterator","GlobIterator","InfiniteIterator","InvalidArgumentException","IteratorIterator","LengthException","LimitIterator","LogicException","MultipleIterator","NoRewindIterator","OutOfBoundsException","OutOfRangeException","OuterIterator","OverflowException","ParentIterator","ParseError","RangeException","RecursiveArrayIterator","RecursiveCachingIterator","RecursiveCallbackFilterIterator","RecursiveDirectoryIterator","RecursiveFilterIterator","RecursiveIterator","RecursiveIteratorIterator","RecursiveRegexIterator","RecursiveTreeIterator","RegexIterator","RuntimeException","SeekableIterator","SplDoublyLinkedList","SplFileInfo","SplFileObject","SplFixedArray","SplHeap","SplMaxHeap","SplMinHeap","SplObjectStorage","SplObserver","SplPriorityQueue","SplQueue","SplStack","SplSubject","SplTempFileObject","TypeError","UnderflowException","UnexpectedValueException","UnhandledMatchError","ArrayAccess","BackedEnum","Closure","Fiber","Generator","Iterator","IteratorAggregate","Serializable","Stringable","Throwable","Traversable","UnitEnum","WeakReference","WeakMap","Directory","__PHP_Incomplete_Class","parent","php_user_filter","self","static","stdClass"],E={keyword:y,literal:(K=>{const O=[];return K.forEach((V=>{O.push(V),V.toLowerCase()===V?O.push(V.toUpperCase()):O.push(V.toLowerCase())})),O})(A),built_in:h},_=K=>K.map((O=>O.replace(/\|\d+$/,""))),N={variants:[{match:[/new/,e.concat(d,"+"),e.concat("(?!",_(h).join("\\b|"),"\\b)"),o],scope:{1:"keyword",4:"title.class"}}]},v=e.concat(r,"\\b(?!\\()"),T={variants:[{match:[e.concat(/::/,e.lookahead(/(?!class\b)/)),v],scope:{2:"variable.constant"}},{match:[/::/,/class/],scope:{2:"variable.language"}},{match:[o,e.concat(/::/,e.lookahead(/(?!class\b)/)),v],scope:{1:"title.class",3:"variable.constant"}},{match:[o,e.concat("::",e.lookahead(/(?!class\b)/))],scope:{1:"title.class"}},{match:[o,/::/,/class/],scope:{1:"title.class",3:"variable.language"}}]},R={scope:"attr",match:e.concat(r,e.lookahead(":"),e.lookahead(/(?!::)/))},H={relevance:0,begin:/\(/,end:/\)/,keywords:E,contains:[R,a,T,t.C_BLOCK_COMMENT_MODE,f,b,N]},I={relevance:0,match:[/\b/,e.concat("(?!fn\\b|function\\b|",_(y).join("\\b|"),"|",_(h).join("\\b|"),"\\b)"),r,e.concat(d,"*"),e.lookahead(/(?=\()/)],scope:{3:"title.function.invoke"},contains:[H]};H.contains.push(I);const W=[R,T,t.C_BLOCK_COMMENT_MODE,f,b,N];return{case_insensitive:!1,keywords:E,contains:[{begin:e.concat(/#\[\s*/,o),beginScope:"meta",end:/]/,endScope:"meta",keywords:{literal:A,keyword:["new","array"]},contains:[{begin:/\[/,end:/]/,keywords:{literal:A,keyword:["new","array"]},contains:["self",...W]},...W,{scope:"meta",match:o}]},t.HASH_COMMENT_MODE,t.COMMENT("//","$"),t.COMMENT("/\\*","\\*/",{contains:[{scope:"doctag",match:"@[A-Za-z]+"}]}),{match:/__halt_compiler\(\);/,keywords:"__halt_compiler",starts:{scope:"comment",end:t.MATCH_NOTHING_RE,contains:[{match:/\?>/,scope:"meta",endsParent:!0}]}},{scope:"meta",variants:[{begin:/<\?php/,relevance:10},{begin:/<\?=/},{begin:/<\?/,relevance:.1},{begin:/\?>/}]},{scope:"variable.language",match:/\$this\b/},a,I,T,{match:[/const/,/\s/,r],scope:{1:"keyword",3:"variable.constant"}},N,{scope:"function",relevance:0,beginKeywords:"fn function",end:/[;{]/,excludeEnd:!0,illegal:"[$%\\[]",contains:[{beginKeywords:"use"},t.UNDERSCORE_TITLE_MODE,{begin:"=>",endsParent:!0},{scope:"params",begin:"\\(",end:"\\)",excludeBegin:!0,excludeEnd:!0,keywords:E,contains:["self",a,T,t.C_BLOCK_COMMENT_MODE,f,b]}]},{scope:"class",variants:[{beginKeywords:"enum",illegal:/[($"]/},{beginKeywords:"class interface trait",illegal:/[:($"]/}],relevance:0,end:/\{/,excludeEnd:!0,contains:[{beginKeywords:"extends implements"},t.UNDERSCORE_TITLE_MODE]},{beginKeywords:"namespace",relevance:0,end:";",illegal:/[.']/,contains:[t.inherit(t.UNDERSCORE_TITLE_MODE,{scope:"title.class"})]},{beginKeywords:"use",relevance:0,end:";",contains:[{match:/\b(as|const|function)\b/,scope:"keyword"},t.UNDERSCORE_TITLE_MODE]},f,b]}})),J.registerLanguage("php-template",(function(t){return{name:"PHP template",subLanguage:"xml",contains:[{begin:/<\?(php|=)?/,end:/\?>/,subLanguage:"php",contains:[{begin:"/\\*",end:"\\*/",skip:!0},{begin:'b"',end:'"',skip:!0},{begin:"b'",end:"'",skip:!0},t.inherit(t.APOS_STRING_MODE,{illegal:null,className:null,contains:null,skip:!0}),t.inherit(t.QUOTE_STRING_MODE,{illegal:null,className:null,contains:null,skip:!0})]}]}})),J.registerLanguage("plaintext",(function(t){return{name:"Plain text",aliases:["text","txt"],disableAutodetect:!0}})),J.registerLanguage("python",(function(t){const e=t.regex,n=new RegExp("[\\p{XID_Start}_]\\p{XID_Continue}*","u"),r=["and","as","assert","async","await","break","case","class","continue","def","del","elif","else","except","finally","for","from","global","if","import","in","is","lambda","match","nonlocal|10","not","or","pass","raise","return","try","while","with","yield"],i={$pattern:/[A-Za-z]\w+|__\w+__/,keyword:r,built_in:["__import__","abs","all","any","ascii","bin","bool","breakpoint","bytearray","bytes","callable","chr","classmethod","compile","complex","delattr","dict","dir","divmod","enumerate","eval","exec","filter","float","format","frozenset","getattr","globals","hasattr","hash","help","hex","id","input","int","isinstance","issubclass","iter","len","list","locals","map","max","memoryview","min","next","object","oct","open","ord","pow","print","property","range","repr","reversed","round","set","setattr","slice","sorted","staticmethod","str","sum","super","tuple","type","vars","zip"],literal:["__debug__","Ellipsis","False","None","NotImplemented","True"],type:["Any","Callable","Coroutine","Dict","List","Literal","Generic","Optional","Sequence","Set","Tuple","Type","Union"]},l={className:"meta",begin:/^(>>>|\.\.\.) /},u={className:"subst",begin:/\{/,end:/\}/,keywords:i,illegal:/#/},c={begin:/\{\{/,relevance:0},p={className:"string",contains:[t.BACKSLASH_ESCAPE],variants:[{begin:/([uU]|[bB]|[rR]|[bB][rR]|[rR][bB])?'''/,end:/'''/,contains:[t.BACKSLASH_ESCAPE,l],relevance:10},{begin:/([uU]|[bB]|[rR]|[bB][rR]|[rR][bB])?"""/,end:/"""/,contains:[t.BACKSLASH_ESCAPE,l],relevance:10},{begin:/([fF][rR]|[rR][fF]|[fF])'''/,end:/'''/,contains:[t.BACKSLASH_ESCAPE,l,c,u]},{begin:/([fF][rR]|[rR][fF]|[fF])"""/,end:/"""/,contains:[t.BACKSLASH_ESCAPE,l,c,u]},{begin:/([uU]|[rR])'/,end:/'/,relevance:10},{begin:/([uU]|[rR])"/,end:/"/,relevance:10},{begin:/([bB]|[bB][rR]|[rR][bB])'/,end:/'/},{begin:/([bB]|[bB][rR]|[rR][bB])"/,end:/"/},{begin:/([fF][rR]|[rR][fF]|[fF])'/,end:/'/,contains:[t.BACKSLASH_ESCAPE,c,u]},{begin:/([fF][rR]|[rR][fF]|[fF])"/,end:/"/,contains:[t.BACKSLASH_ESCAPE,c,u]},t.APOS_STRING_MODE,t.QUOTE_STRING_MODE]},d="[0-9](_?[0-9])*",f=`(\\b(${d}))?\\.(${d})|\\b(${d})\\.`,b=`\\b|${r.join("|")}`,A={className:"number",relevance:0,variants:[{begin:`(\\b(${d})|(${f}))[eE][+-]?(${d})[jJ]?(?=${b})`},{begin:`(${f})[jJ]?`},{begin:`\\b([1-9](_?[0-9])*|0+(_?0)*)[lLjJ]?(?=${b})`},{begin:`\\b0[bB](_?[01])+[lL]?(?=${b})`},{begin:`\\b0[oO](_?[0-7])+[lL]?(?=${b})`},{begin:`\\b0[xX](_?[0-9a-fA-F])+[lL]?(?=${b})`},{begin:`\\b(${d})[jJ](?=${b})`}]},y={className:"comment",begin:e.lookahead(/# type:/),end:/$/,keywords:i,contains:[{begin:/# type:/},{begin:/#/,end:/\b\B/,endsWithParent:!0}]},h={className:"params",variants:[{className:"",begin:/\(\s*\)/,skip:!0},{begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:i,contains:["self",l,A,p,t.HASH_COMMENT_MODE]}]};return u.contains=[p,A,l],{name:"Python",aliases:["py","gyp","ipython"],unicodeRegex:!0,keywords:i,illegal:/(<\/|\?)|=>/,contains:[l,A,{begin:/\bself\b/},{beginKeywords:"if",relevance:0},p,y,t.HASH_COMMENT_MODE,{match:[/\bdef/,/\s+/,n],scope:{1:"keyword",3:"title.function"},contains:[h]},{variants:[{match:[/\bclass/,/\s+/,n,/\s*/,/\(\s*/,n,/\s*\)/]},{match:[/\bclass/,/\s+/,n]}],scope:{1:"keyword",3:"title.class",6:"title.class.inherited"}},{className:"meta",begin:/^[\t ]*@/,end:/(?=#)|$/,contains:[A,h,p]}]}})),J.registerLanguage("python-repl",(function(t){return{aliases:["pycon"],contains:[{className:"meta.prompt",starts:{end:/ |$/,starts:{end:"$",subLanguage:"python"}},variants:[{begin:/^>>>(?=[ ]|$)/},{begin:/^\.\.\.(?=[ ]|$)/}]}]}})),J.registerLanguage("r",(function(t){const e=t.regex,n=/(?:(?:[a-zA-Z]|\.[._a-zA-Z])[._a-zA-Z0-9]*)|\.(?!\d)/,r=e.either(/0[xX][0-9a-fA-F]+\.[0-9a-fA-F]*[pP][+-]?\d+i?/,/0[xX][0-9a-fA-F]+(?:[pP][+-]?\d+)?[Li]?/,/(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?[Li]?/),o=/[=!<>:]=|\|\||&&|:::?|<-|<<-|->>|->|\|>|[-+*\/?!$&|:<=>@^~]|\*\*/,a=e.either(/[()]/,/[{}]/,/\[\[/,/[[\]]/,/\\/,/,/);return{name:"R",keywords:{$pattern:n,keyword:"function if in break next repeat else for while",literal:"NULL NA TRUE FALSE Inf NaN NA_integer_|10 NA_real_|10 NA_character_|10 NA_complex_|10",built_in:"LETTERS letters month.abb month.name pi T F abs acos acosh all any anyNA Arg as.call as.character as.complex as.double as.environment as.integer as.logical as.null.default as.numeric as.raw asin asinh atan atanh attr attributes baseenv browser c call ceiling class Conj cos cosh cospi cummax cummin cumprod cumsum digamma dim dimnames emptyenv exp expression floor forceAndCall gamma gc.time globalenv Im interactive invisible is.array is.atomic is.call is.character is.complex is.double is.environment is.expression is.finite is.function is.infinite is.integer is.language is.list is.logical is.matrix is.na is.name is.nan is.null is.numeric is.object is.pairlist is.raw is.recursive is.single is.symbol lazyLoadDBfetch length lgamma list log max min missing Mod names nargs nzchar oldClass on.exit pos.to.env proc.time prod quote range Re rep retracemem return round seq_along seq_len seq.int sign signif sin sinh sinpi sqrt standardGeneric substitute sum switch tan tanh tanpi tracemem trigamma trunc unclass untracemem UseMethod xtfrm"},contains:[t.COMMENT(/#'/,/$/,{contains:[{scope:"doctag",match:/@examples/,starts:{end:e.lookahead(e.either(/\n^#'\s*(?=@[a-zA-Z]+)/,/\n^(?!#')/)),endsParent:!0}},{scope:"doctag",begin:"@param",end:/$/,contains:[{scope:"variable",variants:[{match:n},{match:/`(?:\\.|[^`\\])+`/}],endsParent:!0}]},{scope:"doctag",match:/@[a-zA-Z]+/},{scope:"keyword",match:/\\[a-zA-Z]+/}]}),t.HASH_COMMENT_MODE,{scope:"string",contains:[t.BACKSLASH_ESCAPE],variants:[t.END_SAME_AS_BEGIN({begin:/[rR]"(-*)\(/,end:/\)(-*)"/}),t.END_SAME_AS_BEGIN({begin:/[rR]"(-*)\{/,end:/\}(-*)"/}),t.END_SAME_AS_BEGIN({begin:/[rR]"(-*)\[/,end:/\](-*)"/}),t.END_SAME_AS_BEGIN({begin:/[rR]'(-*)\(/,end:/\)(-*)'/}),t.END_SAME_AS_BEGIN({begin:/[rR]'(-*)\{/,end:/\}(-*)'/}),t.END_SAME_AS_BEGIN({begin:/[rR]'(-*)\[/,end:/\](-*)'/}),{begin:'"',end:'"',relevance:0},{begin:"'",end:"'",relevance:0}]},{relevance:0,variants:[{scope:{1:"operator",2:"number"},match:[o,r]},{scope:{1:"operator",2:"number"},match:[/%[^%]*%/,r]},{scope:{1:"punctuation",2:"number"},match:[a,r]},{scope:{2:"number"},match:[/[^a-zA-Z0-9._]|^/,r]}]},{scope:{3:"operator"},match:[n,/\s+/,/<-/,/\s+/]},{scope:"operator",relevance:0,variants:[{match:o},{match:/%[^%]*%/}]},{scope:"punctuation",relevance:0,match:a},{begin:"`",end:"`",contains:[{begin:/\\./}]}]}})),J.registerLanguage("ruby",(function(t){const e=t.regex,n="([a-zA-Z_]\\w*[!?=]?|[-+~]@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?)",r=e.either(/\b([A-Z]+[a-z0-9]+)+/,/\b([A-Z]+[a-z0-9]+)+[A-Z]+/),o=e.concat(r,/(::\w+)*/),s={"variable.constant":["__FILE__","__LINE__","__ENCODING__"],"variable.language":["self","super"],keyword:["alias","and","begin","BEGIN","break","case","class","defined","do","else","elsif","end","END","ensure","for","if","in","module","next","not","or","redo","require","rescue","retry","return","then","undef","unless","until","when","while","yield","include","extend","prepend","public","private","protected","raise","throw"],built_in:["proc","lambda","attr_accessor","attr_reader","attr_writer","define_method","private_constant","module_function"],literal:["true","false","nil"]},i={className:"doctag",begin:"@[A-Za-z]+"},l={begin:"#<",end:">"},u=[t.COMMENT("#","$",{contains:[i]}),t.COMMENT("^=begin","^=end",{contains:[i],relevance:10}),t.COMMENT("^__END__",t.MATCH_NOTHING_RE)],c={className:"subst",begin:/#\{/,end:/\}/,keywords:s},p={className:"string",contains:[t.BACKSLASH_ESCAPE,c],variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/`/,end:/`/},{begin:/%[qQwWx]?\(/,end:/\)/},{begin:/%[qQwWx]?\[/,end:/\]/},{begin:/%[qQwWx]?\{/,end:/\}/},{begin:/%[qQwWx]?/},{begin:/%[qQwWx]?\//,end:/\//},{begin:/%[qQwWx]?%/,end:/%/},{begin:/%[qQwWx]?-/,end:/-/},{begin:/%[qQwWx]?\|/,end:/\|/},{begin:/\B\?(\\\d{1,3})/},{begin:/\B\?(\\x[A-Fa-f0-9]{1,2})/},{begin:/\B\?(\\u\{?[A-Fa-f0-9]{1,6}\}?)/},{begin:/\B\?(\\M-\\C-|\\M-\\c|\\c\\M-|\\M-|\\C-\\M-)[\x20-\x7e]/},{begin:/\B\?\\(c|C-)[\x20-\x7e]/},{begin:/\B\?\\?\S/},{begin:e.concat(/<<[-~]?'?/,e.lookahead(/(\w+)(?=\W)[^\n]*\n(?:[^\n]*\n)*?\s*\1\b/)),contains:[t.END_SAME_AS_BEGIN({begin:/(\w+)/,end:/(\w+)/,contains:[t.BACKSLASH_ESCAPE,c]})]}]},f="[0-9](_?[0-9])*",b={className:"number",relevance:0,variants:[{begin:`\\b([1-9](_?[0-9])*|0)(\\.(${f}))?([eE][+-]?(${f})|r)?i?\\b`},{begin:"\\b0[dD][0-9](_?[0-9])*r?i?\\b"},{begin:"\\b0[bB][0-1](_?[0-1])*r?i?\\b"},{begin:"\\b0[oO][0-7](_?[0-7])*r?i?\\b"},{begin:"\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*r?i?\\b"},{begin:"\\b0(_?[0-7])+r?i?\\b"}]},A={variants:[{match:/\(\)/},{className:"params",begin:/\(/,end:/(?=\))/,excludeBegin:!0,endsParent:!0,keywords:s}]},v=[p,{variants:[{match:[/class\s+/,o,/\s+<\s+/,o]},{match:[/\b(class|module)\s+/,o]}],scope:{2:"title.class",4:"title.class.inherited"},keywords:s},{match:[/(include|extend)\s+/,o],scope:{2:"title.class"},keywords:s},{relevance:0,match:[o,/\.new[. (]/],scope:{1:"title.class"}},{relevance:0,match:/\b[A-Z][A-Z_0-9]+\b/,className:"variable.constant"},{relevance:0,match:r,scope:"title.class"},{match:[/def/,/\s+/,n],scope:{1:"keyword",3:"title.function"},contains:[A]},{begin:t.IDENT_RE+"::"},{className:"symbol",begin:t.UNDERSCORE_IDENT_RE+"(!|\\?)?:",relevance:0},{className:"symbol",begin:":(?!\\s)",contains:[p,{begin:n}],relevance:0},b,{className:"variable",begin:"(\\$\\W)|((\\$|@@?)(\\w+))(?=[^@$?])(?![A-Za-z])(?![@$?'])"},{className:"params",begin:/\|/,end:/\|/,excludeBegin:!0,excludeEnd:!0,relevance:0,keywords:s},{begin:"("+t.RE_STARTERS_RE+"|unless)\\s*",keywords:"unless",contains:[{className:"regexp",contains:[t.BACKSLASH_ESCAPE,c],illegal:/\n/,variants:[{begin:"/",end:"/[a-z]*"},{begin:/%r\{/,end:/\}[a-z]*/},{begin:"%r\\(",end:"\\)[a-z]*"},{begin:"%r!",end:"![a-z]*"},{begin:"%r\\[",end:"\\][a-z]*"}]}].concat(l,u),relevance:0}].concat(l,u);c.contains=v,A.contains=v;const I=[{begin:/^\s*=>/,starts:{end:"$",contains:v}},{className:"meta.prompt",begin:"^([>?]>|[\\w#]+\\(\\w+\\):\\d+:\\d+[>*]|(\\w+-)?\\d+\\.\\d+\\.\\d+(p\\d+)?[^\\d][^>]+>)(?=[ ])",starts:{end:"$",keywords:s,contains:v}}];return u.unshift(l),{name:"Ruby",aliases:["rb","gemspec","podspec","thor","irb"],keywords:s,illegal:/\/\*/,contains:[t.SHEBANG({binary:"ruby"})].concat(I).concat(u).concat(v)}})),J.registerLanguage("rust",(function(t){const e=t.regex,n={className:"title.function.invoke",relevance:0,begin:e.concat(/\b/,/(?!let|for|while|if|else|match\b)/,t.IDENT_RE,e.lookahead(/\s*\(/))},r="([ui](8|16|32|64|128|size)|f(32|64))?",s=["drop ","Copy","Send","Sized","Sync","Drop","Fn","FnMut","FnOnce","ToOwned","Clone","Debug","PartialEq","PartialOrd","Eq","Ord","AsRef","AsMut","Into","From","Default","Iterator","Extend","IntoIterator","DoubleEndedIterator","ExactSizeIterator","SliceConcatExt","ToString","assert!","assert_eq!","bitflags!","bytes!","cfg!","col!","concat!","concat_idents!","debug_assert!","debug_assert_eq!","env!","eprintln!","panic!","file!","format!","format_args!","include_bytes!","include_str!","line!","local_data_key!","module_path!","option_env!","print!","println!","select!","stringify!","try!","unimplemented!","unreachable!","vec!","write!","writeln!","macro_rules!","assert_ne!","debug_assert_ne!"],i=["i8","i16","i32","i64","i128","isize","u8","u16","u32","u64","u128","usize","f32","f64","str","char","bool","Box","Option","Result","String","Vec"];return{name:"Rust",aliases:["rs"],keywords:{$pattern:t.IDENT_RE+"!?",type:i,keyword:["abstract","as","async","await","become","box","break","const","continue","crate","do","dyn","else","enum","extern","false","final","fn","for","if","impl","in","let","loop","macro","match","mod","move","mut","override","priv","pub","ref","return","self","Self","static","struct","super","trait","true","try","type","typeof","unsafe","unsized","use","virtual","where","while","yield"],literal:["true","false","Some","None","Ok","Err"],built_in:s},illegal:""},n]}})),J.registerLanguage("scss",(function(t){const e=(t=>({IMPORTANT:{scope:"meta",begin:"!important"},BLOCK_COMMENT:t.C_BLOCK_COMMENT_MODE,HEXCOLOR:{scope:"number",begin:/#(([0-9a-fA-F]{3,4})|(([0-9a-fA-F]{2}){3,4}))\b/},FUNCTION_DISPATCH:{className:"built_in",begin:/[\w-]+(?=\()/},ATTRIBUTE_SELECTOR_MODE:{scope:"selector-attr",begin:/\[/,end:/\]/,illegal:"$",contains:[t.APOS_STRING_MODE,t.QUOTE_STRING_MODE]},CSS_NUMBER_MODE:{scope:"number",begin:t.NUMBER_RE+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",relevance:0},CSS_VARIABLE:{className:"attr",begin:/--[A-Za-z_][A-Za-z0-9_-]*/}}))(t),n=l8,r=i8,o="@[a-z-]+",i={className:"variable",begin:"(\\$[a-zA-Z-][a-zA-Z0-9_-]*)\\b",relevance:0};return{name:"SCSS",case_insensitive:!0,illegal:"[=/|']",contains:[t.C_LINE_COMMENT_MODE,t.C_BLOCK_COMMENT_MODE,e.CSS_NUMBER_MODE,{className:"selector-id",begin:"#[A-Za-z0-9_-]+",relevance:0},{className:"selector-class",begin:"\\.[A-Za-z0-9_-]+",relevance:0},e.ATTRIBUTE_SELECTOR_MODE,{className:"selector-tag",begin:"\\b("+a8.join("|")+")\\b",relevance:0},{className:"selector-pseudo",begin:":("+r.join("|")+")"},{className:"selector-pseudo",begin:":(:)?("+n.join("|")+")"},i,{begin:/\(/,end:/\)/,contains:[e.CSS_NUMBER_MODE]},e.CSS_VARIABLE,{className:"attribute",begin:"\\b("+u8.join("|")+")\\b"},{begin:"\\b(whitespace|wait|w-resize|visible|vertical-text|vertical-ideographic|uppercase|upper-roman|upper-alpha|underline|transparent|top|thin|thick|text|text-top|text-bottom|tb-rl|table-header-group|table-footer-group|sw-resize|super|strict|static|square|solid|small-caps|separate|se-resize|scroll|s-resize|rtl|row-resize|ridge|right|repeat|repeat-y|repeat-x|relative|progress|pointer|overline|outside|outset|oblique|nowrap|not-allowed|normal|none|nw-resize|no-repeat|no-drop|newspaper|ne-resize|n-resize|move|middle|medium|ltr|lr-tb|lowercase|lower-roman|lower-alpha|loose|list-item|line|line-through|line-edge|lighter|left|keep-all|justify|italic|inter-word|inter-ideograph|inside|inset|inline|inline-block|inherit|inactive|ideograph-space|ideograph-parenthesis|ideograph-numeric|ideograph-alpha|horizontal|hidden|help|hand|groove|fixed|ellipsis|e-resize|double|dotted|distribute|distribute-space|distribute-letter|distribute-all-lines|disc|disabled|default|decimal|dashed|crosshair|collapse|col-resize|circle|char|center|capitalize|break-word|break-all|bottom|both|bolder|bold|block|bidi-override|below|baseline|auto|always|all-scroll|absolute|table|table-cell)\\b"},{begin:/:/,end:/[;}{]/,relevance:0,contains:[e.BLOCK_COMMENT,i,e.HEXCOLOR,e.CSS_NUMBER_MODE,t.QUOTE_STRING_MODE,t.APOS_STRING_MODE,e.IMPORTANT,e.FUNCTION_DISPATCH]},{begin:"@(page|font-face)",keywords:{$pattern:o,keyword:"@page @font-face"}},{begin:"@",end:"[{;]",returnBegin:!0,keywords:{$pattern:/[a-z-]+/,keyword:"and or not only",attribute:s8.join(" ")},contains:[{begin:o,className:"keyword"},{begin:/[a-z-]+(?=:)/,className:"attribute"},i,t.QUOTE_STRING_MODE,t.APOS_STRING_MODE,e.HEXCOLOR,e.CSS_NUMBER_MODE]},e.FUNCTION_DISPATCH]}})),J.registerLanguage("shell",(function(t){return{name:"Shell Session",aliases:["console","shellsession"],contains:[{className:"meta.prompt",begin:/^\s{0,3}[/~\w\d[\]()@-]*[>%$#][ ]?/,starts:{end:/[^\\](?=\s*$)/,subLanguage:"bash"}}]}})),J.registerLanguage("sql",(function(t){const e=t.regex,n=t.COMMENT("--","$"),a=["true","false","unknown"],i=["bigint","binary","blob","boolean","char","character","clob","date","dec","decfloat","decimal","float","int","integer","interval","nchar","nclob","national","numeric","real","row","smallint","time","timestamp","varchar","varying","varbinary"],c=["abs","acos","array_agg","asin","atan","avg","cast","ceil","ceiling","coalesce","corr","cos","cosh","count","covar_pop","covar_samp","cume_dist","dense_rank","deref","element","exp","extract","first_value","floor","json_array","json_arrayagg","json_exists","json_object","json_objectagg","json_query","json_table","json_table_primitive","json_value","lag","last_value","lead","listagg","ln","log","log10","lower","max","min","mod","nth_value","ntile","nullif","percent_rank","percentile_cont","percentile_disc","position","position_regex","power","rank","regr_avgx","regr_avgy","regr_count","regr_intercept","regr_r2","regr_slope","regr_sxx","regr_sxy","regr_syy","row_number","sin","sinh","sqrt","stddev_pop","stddev_samp","substring","substring_regex","sum","tan","tanh","translate","translate_regex","treat","trim","trim_array","unnest","upper","value_of","var_pop","var_samp","width_bucket"],d=["create table","insert into","primary key","foreign key","not null","alter table","add constraint","grouping sets","on overflow","character set","respect nulls","ignore nulls","nulls first","nulls last","depth first","breadth first"],f=c,b=["abs","acos","all","allocate","alter","and","any","are","array","array_agg","array_max_cardinality","as","asensitive","asin","asymmetric","at","atan","atomic","authorization","avg","begin","begin_frame","begin_partition","between","bigint","binary","blob","boolean","both","by","call","called","cardinality","cascaded","case","cast","ceil","ceiling","char","char_length","character","character_length","check","classifier","clob","close","coalesce","collate","collect","column","commit","condition","connect","constraint","contains","convert","copy","corr","corresponding","cos","cosh","count","covar_pop","covar_samp","create","cross","cube","cume_dist","current","current_catalog","current_date","current_default_transform_group","current_path","current_role","current_row","current_schema","current_time","current_timestamp","current_path","current_role","current_transform_group_for_type","current_user","cursor","cycle","date","day","deallocate","dec","decimal","decfloat","declare","default","define","delete","dense_rank","deref","describe","deterministic","disconnect","distinct","double","drop","dynamic","each","element","else","empty","end","end_frame","end_partition","end-exec","equals","escape","every","except","exec","execute","exists","exp","external","extract","false","fetch","filter","first_value","float","floor","for","foreign","frame_row","free","from","full","function","fusion","get","global","grant","group","grouping","groups","having","hold","hour","identity","in","indicator","initial","inner","inout","insensitive","insert","int","integer","intersect","intersection","interval","into","is","join","json_array","json_arrayagg","json_exists","json_object","json_objectagg","json_query","json_table","json_table_primitive","json_value","lag","language","large","last_value","lateral","lead","leading","left","like","like_regex","listagg","ln","local","localtime","localtimestamp","log","log10","lower","match","match_number","match_recognize","matches","max","member","merge","method","min","minute","mod","modifies","module","month","multiset","national","natural","nchar","nclob","new","no","none","normalize","not","nth_value","ntile","null","nullif","numeric","octet_length","occurrences_regex","of","offset","old","omit","on","one","only","open","or","order","out","outer","over","overlaps","overlay","parameter","partition","pattern","per","percent","percent_rank","percentile_cont","percentile_disc","period","portion","position","position_regex","power","precedes","precision","prepare","primary","procedure","ptf","range","rank","reads","real","recursive","ref","references","referencing","regr_avgx","regr_avgy","regr_count","regr_intercept","regr_r2","regr_slope","regr_sxx","regr_sxy","regr_syy","release","result","return","returns","revoke","right","rollback","rollup","row","row_number","rows","running","savepoint","scope","scroll","search","second","seek","select","sensitive","session_user","set","show","similar","sin","sinh","skip","smallint","some","specific","specifictype","sql","sqlexception","sqlstate","sqlwarning","sqrt","start","static","stddev_pop","stddev_samp","submultiset","subset","substring","substring_regex","succeeds","sum","symmetric","system","system_time","system_user","table","tablesample","tan","tanh","then","time","timestamp","timezone_hour","timezone_minute","to","trailing","translate","translate_regex","translation","treat","trigger","trim","trim_array","true","truncate","uescape","union","unique","unknown","unnest","update","upper","user","using","value","values","value_of","var_pop","var_samp","varbinary","varchar","varying","versioning","when","whenever","where","width_bucket","window","with","within","without","year","add","asc","collation","desc","final","first","last","view"].filter((E=>!c.includes(E))),h={begin:e.concat(/\b/,e.either(...f),/\s*\(/),relevance:0,keywords:{built_in:f}};return{name:"SQL",case_insensitive:!0,illegal:/[{}]|<\//,keywords:{$pattern:/\b[\w\.]+/,keyword:function(E,{exceptions:_,when:N}={}){const v=N;return _=_||[],E.map((T=>T.match(/\|\d+$/)||_.includes(T)?T:v(T)?`${T}|0`:T))}(b,{when:E=>E.length<3}),literal:a,type:i,built_in:["current_catalog","current_date","current_default_transform_group","current_path","current_role","current_schema","current_transform_group_for_type","current_user","session_user","system_time","system_user","current_time","localtime","current_timestamp","localtimestamp"]},contains:[{begin:e.either(...d),relevance:0,keywords:{$pattern:/[\w\.]+/,keyword:b.concat(d),literal:a,type:i}},{className:"type",begin:e.either("double precision","large object","with timezone","without timezone")},h,{className:"variable",begin:/@[a-z0-9][a-z0-9_]*/},{className:"string",variants:[{begin:/'/,end:/'/,contains:[{begin:/''/}]}]},{begin:/"/,end:/"/,contains:[{begin:/""/}]},t.C_NUMBER_MODE,t.C_BLOCK_COMMENT_MODE,n,{className:"operator",begin:/[-+*/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?/,relevance:0}]}})),J.registerLanguage("swift",(function(t){const e={match:/\s+/,relevance:0},n=t.COMMENT("/\\*","\\*/",{contains:["self"]}),r=[t.C_LINE_COMMENT_MODE,n],o={match:[/\./,it(...m8,...Rm)],className:{2:"keyword"}},a={match:fe(/\./,it(...rc)),relevance:0},s=rc.filter((ne=>"string"==typeof ne)).concat(["_|0"]),l={variants:[{className:"keyword",match:it(...rc.filter((ne=>"string"!=typeof ne)).concat(g8).map(nc),...Rm)}]},u={$pattern:it(/\b\w+/,/#\w+/),keyword:s.concat(E8),literal:Lm},c=[o,a,l],f=[{match:fe(/\./,it(...Om)),relevance:0},{className:"built_in",match:fe(/\b/,it(...Om),/(?=\()/)}],b={match:/->/,relevance:0},y=[b,{className:"operator",relevance:0,variants:[{match:oc},{match:`\\.(\\.|${Im})+`}]}],h="([0-9]_*)+",g="([0-9a-fA-F]_*)+",E={className:"number",relevance:0,variants:[{match:`\\b(${h})(\\.(${h}))?([eE][+-]?(${h}))?\\b`},{match:`\\b0x(${g})(\\.(${g}))?([pP][+-]?(${h}))?\\b`},{match:/\b0o([0-7]_*)+\b/},{match:/\b0b([01]_*)+\b/}]},_=(ne="")=>({className:"subst",variants:[{match:fe(/\\/,ne,/[0\\tnr"']/)},{match:fe(/\\/,ne,/u\{[0-9a-fA-F]{1,8}\}/)}]}),N=(ne="")=>({className:"subst",match:fe(/\\/,ne,/[\t ]*(?:[\r\n]|\r\n)/)}),v=(ne="")=>({className:"subst",label:"interpol",begin:fe(/\\/,ne,/\(/),end:/\)/}),T=(ne="")=>({begin:fe(ne,/"""/),end:fe(/"""/,ne),contains:[_(ne),N(ne),v(ne)]}),R=(ne="")=>({begin:fe(ne,/"/),end:fe(/"/,ne),contains:[_(ne),v(ne)]}),H={className:"string",variants:[T(),T("#"),T("##"),T("###"),R(),R("#"),R("##"),R("###")]},I=[t.BACKSLASH_ESCAPE,{begin:/\[/,end:/\]/,relevance:0,contains:[t.BACKSLASH_ESCAPE]}],W={begin:/\/[^\s](?=[^/\n]*\/)/,end:/\//,contains:I},le=ne=>{const Oe=fe(ne,/\//),Be=fe(/\//,ne);return{begin:Oe,end:Be,contains:[...I,{scope:"comment",begin:`#(?!.*${Be})`,end:/$/}]}},K={scope:"regexp",variants:[le("###"),le("##"),le("#"),W]},O={match:fe(/`/,cn,/`/)},x=[O,{className:"variable",match:/\$\d+/},{className:"variable",match:`\\$${Ws}+`}],k=[{match:/(@|#(un)?)available/,scope:"keyword",starts:{contains:[{begin:/\(/,end:/\)/,keywords:A8,contains:[...y,E,H]}]}},{scope:"keyword",match:fe(/@/,it(...b8))},{scope:"meta",match:fe(/@/,cn)}],$={match:js(/\b[A-Z]/),relevance:0,contains:[{className:"type",match:fe(/(AV|CA|CF|CG|CI|CL|CM|CN|CT|MK|MP|MTK|MTL|NS|SCN|SK|UI|WK|XC)/,Ws,"+")},{className:"type",match:ac,relevance:0},{match:/[?!]+/,relevance:0},{match:/\.\.\./,relevance:0},{match:fe(/\s+&\s+/,js(ac)),relevance:0}]},j={begin://,keywords:u,contains:[...r,...c,...k,b,$]};$.contains.push(j);const pe={begin:/\(/,end:/\)/,relevance:0,keywords:u,contains:["self",{match:fe(cn,/\s*:/),keywords:"_|0",relevance:0},...r,K,...c,...f,...y,E,H,...x,...k,$]},ue={begin://,keywords:"repeat each",contains:[...r,$]},bt={begin:/\(/,end:/\)/,keywords:u,contains:[{begin:it(js(fe(cn,/\s*:/)),js(fe(cn,/\s+/,cn,/\s*:/))),end:/:/,relevance:0,contains:[{className:"keyword",match:/\b_\b/},{className:"params",match:cn}]},...r,...c,...y,E,H,...k,$,pe],endsParent:!0,illegal:/["']/},Ut={match:[/(func|macro)/,/\s+/,it(O.match,cn,oc)],className:{1:"keyword",3:"title.function"},contains:[ue,bt,e],illegal:[/\[/,/%/]},At={match:[/\b(?:subscript|init[?!]?)/,/\s*(?=[<(])/],className:{1:"keyword"},contains:[ue,bt,e],illegal:/\[|%/},je={match:[/operator/,/\s+/,oc],className:{1:"keyword",3:"title"}},xt={begin:[/precedencegroup/,/\s+/,ac],className:{1:"keyword",3:"title"},contains:[$],keywords:[...h8,...Lm],end:/}/};for(const ne of H.variants){const Oe=ne.contains.find((Ne=>"interpol"===Ne.label));Oe.keywords=u;const Be=[...c,...f,...y,E,H,...x];Oe.contains=[...Be,{begin:/\(/,end:/\)/,contains:["self",...Be]}]}return{name:"Swift",keywords:u,contains:[...r,Ut,At,{beginKeywords:"struct protocol class extension enum actor",end:"\\{",excludeEnd:!0,keywords:u,contains:[t.inherit(t.TITLE_MODE,{className:"title.class",begin:/[A-Za-z$_][\u00C0-\u02B80-9A-Za-z$_]*/}),...c]},je,xt,{beginKeywords:"import",end:/$/,contains:[...r],relevance:0},K,...c,...f,...y,E,H,...x,...k,$,pe]}})),J.registerLanguage("typescript",(function(t){const e=function(t){const e=t.regex,r=Ks,o_begin="<>",o_end="",s={begin:/<[A-Za-z0-9\\._:-]+/,end:/\/[A-Za-z0-9\\._:-]+>|\/>/,isTrulyOpeningTag:(S,C)=>{const L=S[0].length+S.index,k=S.input[L];if("<"===k||","===k)return void C.ignoreMatch();let $;">"===k&&(((S,{after:C})=>{const L="",x={match:[/const|var|let/,/\s+/,r,/\s*/,/=\s*/,/(async\s*)?/,e.lookahead(B)],keywords:"async",className:{1:"keyword",3:"title.function"},contains:[v]};var S;return{name:"JavaScript",aliases:["js","jsx","mjs","cjs"],keywords:i,exports:{PARAMS_CONTAINS:N,CLASS_REFERENCE:R},illegal:/#(?![$_A-z])/,contains:[t.SHEBANG({label:"shebang",binary:"node",relevance:5}),{label:"use_strict",className:"meta",relevance:10,begin:/^\s*['"]use (strict|asm)['"]/},t.APOS_STRING_MODE,t.QUOTE_STRING_MODE,f,b,A,y,g,{match:/\$\d+/},p,R,{className:"attr",begin:r+e.lookahead(":"),relevance:0},x,{begin:"("+t.RE_STARTERS_RE+"|\\b(case|return|throw)\\b)\\s*",keywords:"return throw case",relevance:0,contains:[g,t.REGEXP_MODE,{className:"function",begin:B,returnBegin:!0,end:"\\s*=>",contains:[{className:"params",variants:[{begin:t.UNDERSCORE_IDENT_RE,relevance:0},{className:null,begin:/\(\s*\)/,skip:!0},{begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:i,contains:N}]}]},{begin:/,/,relevance:0},{match:/\s+/,relevance:0},{variants:[{begin:o_begin,end:o_end},{match:/<[A-Za-z0-9\\._:-]+\s*\/>/},{begin:s.begin,"on:begin":s.isTrulyOpeningTag,end:s.end}],subLanguage:"xml",contains:[{begin:s.begin,end:s.end,skip:!0,contains:["self"]}]}]},I,{beginKeywords:"while if switch catch for"},{begin:"\\b(?!function)"+t.UNDERSCORE_IDENT_RE+"\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)\\s*\\{",returnBegin:!0,label:"func.def",contains:[v,t.inherit(t.TITLE_MODE,{begin:r,className:"title.function"})]},{match:/\.\.\./,relevance:0},O,{match:"\\$"+r,relevance:0},{match:[/\bconstructor(?=\s*\()/],className:{1:"title.function"},contains:[v]},K,{relevance:0,match:/\b[A-Z][A-Z_0-9]+\b/,className:"variable.constant"},T,V,{match:/\$[(.]/}]}}(t),n=Ks,r=["any","void","number","boolean","string","object","never","symbol","bigint","unknown"],o={beginKeywords:"namespace",end:/\{/,excludeEnd:!0,contains:[e.exports.CLASS_REFERENCE]},a={beginKeywords:"interface",end:/\{/,excludeEnd:!0,keywords:{keyword:"interface extends",built_in:r},contains:[e.exports.CLASS_REFERENCE]},l={$pattern:Ks,keyword:Fm.concat(["type","namespace","interface","public","private","protected","implements","declare","abstract","readonly","enum","override"]),literal:Bm,built_in:Vm.concat(r),"variable.language":Hm},u={className:"meta",begin:"@"+n},c=(d,f,b)=>{const A=d.contains.findIndex((y=>y.label===f));if(-1===A)throw new Error("can not find mode to replace");d.contains.splice(A,1,b)};return Object.assign(e.keywords,l),e.exports.PARAMS_CONTAINS.push(u),e.contains=e.contains.concat([u,o,a]),c(e,"shebang",t.SHEBANG()),c(e,"use_strict",{className:"meta",relevance:10,begin:/^\s*['"]use strict['"]/}),e.contains.find((d=>"func.def"===d.label)).relevance=0,Object.assign(e,{name:"TypeScript",aliases:["ts","tsx","mts","cts"]}),e})),J.registerLanguage("vbnet",(function(t){const e=t.regex,o=/\d{1,2}\/\d{1,2}\/\d{4}/,a=/\d{4}-\d{1,2}-\d{1,2}/,s=/(\d|1[012])(:\d+){0,2} *(AM|PM)/,i=/\d{1,2}(:\d{1,2}){1,2}/,l={className:"literal",variants:[{begin:e.concat(/# */,e.either(a,o),/ *#/)},{begin:e.concat(/# */,i,/ *#/)},{begin:e.concat(/# */,s,/ *#/)},{begin:e.concat(/# */,e.either(a,o),/ +/,e.either(s,i),/ *#/)}]},p=t.COMMENT(/'''/,/$/,{contains:[{className:"doctag",begin:/<\/?/,end:/>/}]}),d=t.COMMENT(null,/$/,{variants:[{begin:/'/},{begin:/([\t ]|^)REM(?=\s)/}]});return{name:"Visual Basic .NET",aliases:["vb"],case_insensitive:!0,classNameAliases:{label:"symbol"},keywords:{keyword:"addhandler alias aggregate ansi as async assembly auto binary by byref byval call case catch class compare const continue custom declare default delegate dim distinct do each equals else elseif end enum erase error event exit explicit finally for friend from function get global goto group handles if implements imports in inherits interface into iterator join key let lib loop me mid module mustinherit mustoverride mybase myclass namespace narrowing new next notinheritable notoverridable of off on operator option optional order overloads overridable overrides paramarray partial preserve private property protected public raiseevent readonly redim removehandler resume return select set shadows shared skip static step stop structure strict sub synclock take text then throw to try unicode until using when where while widening with withevents writeonly yield",built_in:"addressof and andalso await directcast gettype getxmlnamespace is isfalse isnot istrue like mod nameof new not or orelse trycast typeof xor cbool cbyte cchar cdate cdbl cdec cint clng cobj csbyte cshort csng cstr cuint culng cushort",type:"boolean byte char date decimal double integer long object sbyte short single string uinteger ulong ushort",literal:"true false nothing"},illegal:"//|\\{|\\}|endif|gosub|variant|wend|^\\$ ",contains:[{className:"string",begin:/"(""|[^/n])"C\b/},{className:"string",begin:/"/,end:/"/,illegal:/\n/,contains:[{begin:/""/}]},l,{className:"number",relevance:0,variants:[{begin:/\b\d[\d_]*((\.[\d_]+(E[+-]?[\d_]+)?)|(E[+-]?[\d_]+))[RFD@!#]?/},{begin:/\b\d[\d_]*((U?[SIL])|[%&])?/},{begin:/&H[\dA-F_]+((U?[SIL])|[%&])?/},{begin:/&O[0-7_]+((U?[SIL])|[%&])?/},{begin:/&B[01_]+((U?[SIL])|[%&])?/}]},{className:"label",begin:/^\w+:/},p,d,{className:"meta",begin:/[\t ]*#(const|disable|else|elseif|enable|end|externalsource|if|region)\b/,end:/$/,keywords:{keyword:"const disable else elseif enable end externalsource if region then"},contains:[d]}]}})),J.registerLanguage("wasm",(function(t){t.regex;const e=t.COMMENT(/\(;/,/;\)/);return e.contains.push("self"),{name:"WebAssembly",keywords:{$pattern:/[\w.]+/,keyword:["anyfunc","block","br","br_if","br_table","call","call_indirect","data","drop","elem","else","end","export","func","global.get","global.set","local.get","local.set","local.tee","get_global","get_local","global","if","import","local","loop","memory","memory.grow","memory.size","module","mut","nop","offset","param","result","return","select","set_global","set_local","start","table","tee_local","then","type","unreachable"]},contains:[t.COMMENT(/;;/,/$/),e,{match:[/(?:offset|align)/,/\s*/,/=/],className:{1:"keyword",3:"operator"}},{className:"variable",begin:/\$[\w_]+/},{match:/(\((?!;)|\))+/,className:"punctuation",relevance:0},{begin:[/(?:func|call|call_indirect)/,/\s+/,/\$[^\s)]+/],className:{1:"keyword",3:"title.function"}},t.QUOTE_STRING_MODE,{match:/(i32|i64|f32|f64)(?!\.)/,className:"type"},{className:"keyword",match:/\b(f32|f64|i32|i64)(?:\.(?:abs|add|and|ceil|clz|const|convert_[su]\/i(?:32|64)|copysign|ctz|demote\/f64|div(?:_[su])?|eqz?|extend_[su]\/i32|floor|ge(?:_[su])?|gt(?:_[su])?|le(?:_[su])?|load(?:(?:8|16|32)_[su])?|lt(?:_[su])?|max|min|mul|nearest|neg?|or|popcnt|promote\/f32|reinterpret\/[fi](?:32|64)|rem_[su]|rot[lr]|shl|shr_[su]|store(?:8|16|32)?|sqrt|sub|trunc(?:_[su]\/f(?:32|64))?|wrap\/i64|xor))\b/},{className:"number",relevance:0,match:/[+-]?\b(?:\d(?:_?\d)*(?:\.\d(?:_?\d)*)?(?:[eE][+-]?\d(?:_?\d)*)?|0x[\da-fA-F](?:_?[\da-fA-F])*(?:\.[\da-fA-F](?:_?[\da-fA-D])*)?(?:[pP][+-]?\d(?:_?\d)*)?)\b|\binf\b|\bnan(?::0x[\da-fA-F](?:_?[\da-fA-D])*)?\b/}]}})),J.registerLanguage("xml",(function(t){const e=t.regex,n=e.concat(/[\p{L}_]/u,e.optional(/[\p{L}0-9_.-]*:/u),/[\p{L}0-9_.-]*/u),o={className:"symbol",begin:/&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;/},a={begin:/\s/,contains:[{className:"keyword",begin:/#?[a-z_][a-z1-9_-]+/,illegal:/\n/}]},s=t.inherit(a,{begin:/\(/,end:/\)/}),i=t.inherit(t.APOS_STRING_MODE,{className:"string"}),l=t.inherit(t.QUOTE_STRING_MODE,{className:"string"}),u={endsWithParent:!0,illegal:/`]+/}]}]}]};return{name:"HTML, XML",aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist","wsf","svg"],case_insensitive:!0,unicodeRegex:!0,contains:[{className:"meta",begin://,relevance:10,contains:[a,l,i,s,{begin:/\[/,end:/\]/,contains:[{className:"meta",begin://,contains:[a,s,l,i]}]}]},t.COMMENT(//,{relevance:10}),{begin://,relevance:10},o,{className:"meta",end:/\?>/,variants:[{begin:/<\?xml/,relevance:10,contains:[l]},{begin:/<\?[a-z][a-z0-9]+/}]},{className:"tag",begin:/)/,end:/>/,keywords:{name:"style"},contains:[u],starts:{end:/<\/style>/,returnEnd:!0,subLanguage:["css","xml"]}},{className:"tag",begin:/)/,end:/>/,keywords:{name:"script"},contains:[u],starts:{end:/<\/script>/,returnEnd:!0,subLanguage:["javascript","handlebars","xml"]}},{className:"tag",begin:/<>|<\/>/},{className:"tag",begin:e.concat(//,/>/,/\s/)))),end:/\/?>/,contains:[{className:"name",begin:n,relevance:0,starts:u}]},{className:"tag",begin:e.concat(/<\//,e.lookahead(e.concat(n,/>/))),contains:[{className:"name",begin:n,relevance:0},{begin:/>/,relevance:0,endsParent:!0}]}]}})),J.registerLanguage("yaml",(function(t){const e="true false yes no null",n="[\\w#;/?:@&=+$,.~*'()[\\]]+",a={className:"string",relevance:0,variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/\S+/}],contains:[t.BACKSLASH_ESCAPE,{className:"template-variable",variants:[{begin:/\{\{/,end:/\}\}/},{begin:/%\{/,end:/\}/}]}]},s=t.inherit(a,{variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/[^\s,{}[\]]+/}]}),d={end:",",endsWithParent:!0,excludeEnd:!0,keywords:e,relevance:0},f={begin:/\{/,end:/\}/,contains:[d],illegal:"\\n",relevance:0},b={begin:"\\[",end:"\\]",contains:[d],illegal:"\\n",relevance:0},A=[{className:"attr",variants:[{begin:"\\w[\\w :\\/.-]*:(?=[ \t]|$)"},{begin:'"\\w[\\w :\\/.-]*":(?=[ \t]|$)'},{begin:"'\\w[\\w :\\/.-]*':(?=[ \t]|$)"}]},{className:"meta",begin:"^---\\s*$",relevance:10},{className:"string",begin:"[\\|>]([1-9]?[+-])?[ ]*\\n( +)[^ ][^\\n]*\\n(\\2[^\\n]+\\n?)*"},{begin:"<%[%=-]?",end:"[%-]?%>",subLanguage:"ruby",excludeBegin:!0,excludeEnd:!0,relevance:0},{className:"type",begin:"!\\w+!"+n},{className:"type",begin:"!<"+n+">"},{className:"type",begin:"!"+n},{className:"type",begin:"!!"+n},{className:"meta",begin:"&"+t.UNDERSCORE_IDENT_RE+"$"},{className:"meta",begin:"\\*"+t.UNDERSCORE_IDENT_RE+"$"},{className:"bullet",begin:"-(?=[ ]|$)",relevance:0},t.HASH_COMMENT_MODE,{beginKeywords:e,keywords:{literal:e}},{className:"number",begin:"\\b[0-9]{4}(-[0-9][0-9]){0,2}([Tt \\t][0-9][0-9]?(:[0-9][0-9]){2})?(\\.[0-9]*)?([ \\t])*(Z|[-+][0-9][0-9]?(:[0-9][0-9])?)?\\b"},{className:"number",begin:t.C_NUMBER_RE+"\\b",relevance:0},f,b,a],y=[...A];return y.pop(),y.push(s),d.contains=y,{name:"YAML",case_insensitive:!0,aliases:["yml"],contains:A}}));const $m=J,zm=AD({html:!1,typographer:!0,highlight:function(t,e){const n=Kn();if(e&&$m.getLanguage(e))try{return`
\n
\n ${e}\n \n
\n
\n
`+$m.highlight(t,{language:e,ignoreIllegals:!0}).value+"
"}catch{}return`
\n
\n plaintext\n \n
\n
\n
`+R_.encode(t)+"
"}}).disable("list");function Gm(t=""){return zm.render(t)}/*! @license DOMPurify 3.0.8 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.0.8/LICENSE */zm.renderer.rules.link_open=(t,e)=>``;const{entries:Zm,setPrototypeOf:jm,isFrozen:T8,getPrototypeOf:w8,getOwnPropertyDescriptor:sc}=Object;let{freeze:tt,seal:Pt,create:Wm}=Object,{apply:ic,construct:lc}=typeof Reflect<"u"&&Reflect;tt||(tt=function(e){return e}),Pt||(Pt=function(e){return e}),ic||(ic=function(e,n,r){return e.apply(n,r)}),lc||(lc=function(e,n){return new e(...n)});const Ys=wt(Array.prototype.forEach),Km=wt(Array.prototype.pop),jo=wt(Array.prototype.push),Xs=wt(String.prototype.toLowerCase),uc=wt(String.prototype.toString),x8=wt(String.prototype.match),Wo=wt(String.prototype.replace),R8=wt(String.prototype.indexOf),L8=wt(String.prototype.trim),Et=wt(RegExp.prototype.test),Ko=function(t){return function(){for(var e=arguments.length,n=new Array(e),r=0;r1?n-1:0),o=1;o2&&void 0!==arguments[2]?arguments[2]:Xs;jm&&jm(t,null);let r=e.length;for(;r--;){let o=e[r];if("string"==typeof o){const a=n(o);a!==o&&(T8(e)||(e[r]=a),o=a)}t[o]=!0}return t}function k8(t){for(let e=0;e/gm),P8=Pt(/\${[\w\W]*}/gm),U8=Pt(/^data-[\-\w.\u00B7-\uFFFF]/),q8=Pt(/^aria-[\-\w]+$/),eg=Pt(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),H8=Pt(/^(?:\w+script|data):/i),V8=Pt(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),tg=Pt(/^html$/i);var ng=Object.freeze({__proto__:null,MUSTACHE_EXPR:F8,ERB_EXPR:B8,TMPLIT_EXPR:P8,DATA_ATTR:U8,ARIA_ATTR:q8,IS_ALLOWED_URI:eg,IS_SCRIPT_OR_DATA:H8,ATTR_WHITESPACE:V8,DOCTYPE_NAME:tg});var G8=function rg(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:typeof window>"u"?null:window;const e=Z=>rg(Z);if(e.version="3.0.8",e.removed=[],!t||!t.document||9!==t.document.nodeType)return e.isSupported=!1,e;let{document:n}=t;const r=n,o=r.currentScript,{DocumentFragment:a,HTMLTemplateElement:s,Node:i,Element:l,NodeFilter:u,NamedNodeMap:c=t.NamedNodeMap||t.MozNamedAttrMap,HTMLFormElement:p,DOMParser:d,trustedTypes:f}=t,b=l.prototype,A=Qs(b,"cloneNode"),y=Qs(b,"nextSibling"),h=Qs(b,"childNodes"),g=Qs(b,"parentNode");if("function"==typeof s){const Z=n.createElement("template");Z.content&&Z.content.ownerDocument&&(n=Z.content.ownerDocument)}let E,_="";const{implementation:N,createNodeIterator:v,createDocumentFragment:T,getElementsByTagName:R}=n,{importNode:H}=r;let I={};e.isSupported="function"==typeof Zm&&"function"==typeof g&&N&&void 0!==N.createHTMLDocument;const{MUSTACHE_EXPR:W,ERB_EXPR:le,TMPLIT_EXPR:K,DATA_ATTR:O,ARIA_ATTR:V,IS_SCRIPT_OR_DATA:B,ATTR_WHITESPACE:x}=ng;let{IS_ALLOWED_URI:S}=ng,C=null;const L=ee({},[...Ym,...cc,...dc,...pc,...Xm]);let k=null;const $=ee({},[...Qm,...fc,...Jm,...Js]);let j=Object.seal(Wm(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),ge=null,pe=null,ue=!0,ce=!0,bt=!1,Ut=!0,At=!1,je=!1,xt=!1,ne=!1,Oe=!1,Be=!1,Ne=!1,si=!0,Gr=!1,Zr=!0,Ce=!1,se={},qt=null;const Qt=ee({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","style","svg","template","thead","title","video","xmp"]);let jr=null;const Wr=ee({},["audio","video","img","source","image","track"]);let P=null;const z=ee({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),Q="http://www.w3.org/1998/Math/MathML",re="http://www.w3.org/2000/svg",he="http://www.w3.org/1999/xhtml";let We=he,na=!1,ra=null;const XS=ee({},[Q,re,he],uc);let oa=null;const QS=["application/xhtml+xml","text/html"];let Pe=null,Kr=null;const eN=n.createElement("form"),$g=function(D){return D instanceof RegExp||D instanceof Function},yc=function(){let D=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(!Kr||Kr!==D){if((!D||"object"!=typeof D)&&(D={}),D=tr(D),oa=-1===QS.indexOf(D.PARSER_MEDIA_TYPE)?"text/html":D.PARSER_MEDIA_TYPE,Pe="application/xhtml+xml"===oa?uc:Xs,C="ALLOWED_TAGS"in D?ee({},D.ALLOWED_TAGS,Pe):L,k="ALLOWED_ATTR"in D?ee({},D.ALLOWED_ATTR,Pe):$,ra="ALLOWED_NAMESPACES"in D?ee({},D.ALLOWED_NAMESPACES,uc):XS,P="ADD_URI_SAFE_ATTR"in D?ee(tr(z),D.ADD_URI_SAFE_ATTR,Pe):z,jr="ADD_DATA_URI_TAGS"in D?ee(tr(Wr),D.ADD_DATA_URI_TAGS,Pe):Wr,qt="FORBID_CONTENTS"in D?ee({},D.FORBID_CONTENTS,Pe):Qt,ge="FORBID_TAGS"in D?ee({},D.FORBID_TAGS,Pe):{},pe="FORBID_ATTR"in D?ee({},D.FORBID_ATTR,Pe):{},se="USE_PROFILES"in D&&D.USE_PROFILES,ue=!1!==D.ALLOW_ARIA_ATTR,ce=!1!==D.ALLOW_DATA_ATTR,bt=D.ALLOW_UNKNOWN_PROTOCOLS||!1,Ut=!1!==D.ALLOW_SELF_CLOSE_IN_ATTR,At=D.SAFE_FOR_TEMPLATES||!1,je=D.WHOLE_DOCUMENT||!1,Oe=D.RETURN_DOM||!1,Be=D.RETURN_DOM_FRAGMENT||!1,Ne=D.RETURN_TRUSTED_TYPE||!1,ne=D.FORCE_BODY||!1,si=!1!==D.SANITIZE_DOM,Gr=D.SANITIZE_NAMED_PROPS||!1,Zr=!1!==D.KEEP_CONTENT,Ce=D.IN_PLACE||!1,S=D.ALLOWED_URI_REGEXP||eg,We=D.NAMESPACE||he,j=D.CUSTOM_ELEMENT_HANDLING||{},D.CUSTOM_ELEMENT_HANDLING&&$g(D.CUSTOM_ELEMENT_HANDLING.tagNameCheck)&&(j.tagNameCheck=D.CUSTOM_ELEMENT_HANDLING.tagNameCheck),D.CUSTOM_ELEMENT_HANDLING&&$g(D.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)&&(j.attributeNameCheck=D.CUSTOM_ELEMENT_HANDLING.attributeNameCheck),D.CUSTOM_ELEMENT_HANDLING&&"boolean"==typeof D.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements&&(j.allowCustomizedBuiltInElements=D.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements),At&&(ce=!1),Be&&(Oe=!0),se&&(C=ee({},Xm),k=[],!0===se.html&&(ee(C,Ym),ee(k,Qm)),!0===se.svg&&(ee(C,cc),ee(k,fc),ee(k,Js)),!0===se.svgFilters&&(ee(C,dc),ee(k,fc),ee(k,Js)),!0===se.mathMl&&(ee(C,pc),ee(k,Jm),ee(k,Js))),D.ADD_TAGS&&(C===L&&(C=tr(C)),ee(C,D.ADD_TAGS,Pe)),D.ADD_ATTR&&(k===$&&(k=tr(k)),ee(k,D.ADD_ATTR,Pe)),D.ADD_URI_SAFE_ATTR&&ee(P,D.ADD_URI_SAFE_ATTR,Pe),D.FORBID_CONTENTS&&(qt===Qt&&(qt=tr(qt)),ee(qt,D.FORBID_CONTENTS,Pe)),Zr&&(C["#text"]=!0),je&&ee(C,["html","head","body"]),C.table&&(ee(C,["tbody"]),delete ge.tbody),D.TRUSTED_TYPES_POLICY){if("function"!=typeof D.TRUSTED_TYPES_POLICY.createHTML)throw Ko('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');if("function"!=typeof D.TRUSTED_TYPES_POLICY.createScriptURL)throw Ko('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');E=D.TRUSTED_TYPES_POLICY,_=E.createHTML("")}else void 0===E&&(E=function(e,n){if("object"!=typeof e||"function"!=typeof e.createPolicy)return null;let r=null;const o="data-tt-policy-suffix";n&&n.hasAttribute(o)&&(r=n.getAttribute(o));const a="dompurify"+(r?"#"+r:"");try{return e.createPolicy(a,{createHTML:s=>s,createScriptURL:s=>s})}catch{return console.warn("TrustedTypes policy "+a+" could not be created."),null}}(f,o)),null!==E&&"string"==typeof _&&(_=E.createHTML(""));tt&&tt(D),Kr=D}},zg=ee({},["mi","mo","mn","ms","mtext"]),Gg=ee({},["foreignobject","desc","title","annotation-xml"]),tN=ee({},["title","style","font","a","script"]),Zg=ee({},[...cc,...dc,...I8]),jg=ee({},[...pc,...M8]),rr=function(D){jo(e.removed,{element:D});try{D.parentNode.removeChild(D)}catch{D.remove()}},Dc=function(D,F){try{jo(e.removed,{attribute:F.getAttributeNode(D),from:F})}catch{jo(e.removed,{attribute:null,from:F})}if(F.removeAttribute(D),"is"===D&&!k[D])if(Oe||Be)try{rr(F)}catch{}else try{F.setAttribute(D,"")}catch{}},Wg=function(D){let F=null,G=null;if(ne)D=""+D;else{const Ye=x8(D,/^[\r\n\t ]+/);G=Ye&&Ye[0]}"application/xhtml+xml"===oa&&We===he&&(D=''+D+"");const Ee=E?E.createHTML(D):D;if(We===he)try{F=(new d).parseFromString(Ee,oa)}catch{}if(!F||!F.documentElement){F=N.createDocument(We,"template",null);try{F.documentElement.innerHTML=na?_:Ee}catch{}}const Ke=F.body||F.documentElement;return D&&G&&Ke.insertBefore(n.createTextNode(G),Ke.childNodes[0]||null),We===he?R.call(F,je?"html":"body")[0]:je?F.documentElement:Ke},Kg=function(D){return v.call(D.ownerDocument||D,D,u.SHOW_ELEMENT|u.SHOW_COMMENT|u.SHOW_TEXT,null)},Yg=function(D){return"function"==typeof i&&D instanceof i},dn=function(D,F,G){I[D]&&Ys(I[D],(Ee=>{Ee.call(e,F,G,Kr)}))},Xg=function(D){let F=null;if(dn("beforeSanitizeElements",D,null),function(D){return D instanceof p&&("string"!=typeof D.nodeName||"string"!=typeof D.textContent||"function"!=typeof D.removeChild||!(D.attributes instanceof c)||"function"!=typeof D.removeAttribute||"function"!=typeof D.setAttribute||"string"!=typeof D.namespaceURI||"function"!=typeof D.insertBefore||"function"!=typeof D.hasChildNodes)}(D))return rr(D),!0;const G=Pe(D.nodeName);if(dn("uponSanitizeElement",D,{tagName:G,allowedTags:C}),D.hasChildNodes()&&!Yg(D.firstElementChild)&&Et(/<[/\w]/g,D.innerHTML)&&Et(/<[/\w]/g,D.textContent))return rr(D),!0;if(!C[G]||ge[G]){if(!ge[G]&&Jg(G)&&(j.tagNameCheck instanceof RegExp&&Et(j.tagNameCheck,G)||j.tagNameCheck instanceof Function&&j.tagNameCheck(G)))return!1;if(Zr&&!qt[G]){const Ee=g(D)||D.parentNode,Ke=h(D)||D.childNodes;if(Ke&&Ee){for(let lt=Ke.length-1;lt>=0;--lt)Ee.insertBefore(A(Ke[lt],!0),y(D))}}return rr(D),!0}return D instanceof l&&!function(D){let F=g(D);(!F||!F.tagName)&&(F={namespaceURI:We,tagName:"template"});const G=Xs(D.tagName),Ee=Xs(F.tagName);return!!ra[D.namespaceURI]&&(D.namespaceURI===re?F.namespaceURI===he?"svg"===G:F.namespaceURI===Q?"svg"===G&&("annotation-xml"===Ee||zg[Ee]):!!Zg[G]:D.namespaceURI===Q?F.namespaceURI===he?"math"===G:F.namespaceURI===re?"math"===G&&Gg[Ee]:!!jg[G]:D.namespaceURI===he?!(F.namespaceURI===re&&!Gg[Ee]||F.namespaceURI===Q&&!zg[Ee])&&!jg[G]&&(tN[G]||!Zg[G]):!("application/xhtml+xml"!==oa||!ra[D.namespaceURI]))}(D)||("noscript"===G||"noembed"===G||"noframes"===G)&&Et(/<\/no(script|embed|frames)/i,D.innerHTML)?(rr(D),!0):(At&&3===D.nodeType&&(F=D.textContent,Ys([W,le,K],(Ee=>{F=Wo(F,Ee," ")})),D.textContent!==F&&(jo(e.removed,{element:D.cloneNode()}),D.textContent=F)),dn("afterSanitizeElements",D,null),!1)},Qg=function(D,F,G){if(si&&("id"===F||"name"===F)&&(G in n||G in eN))return!1;if((!ce||pe[F]||!Et(O,F))&&(!ue||!Et(V,F)))if(!k[F]||pe[F]){if(!(Jg(D)&&(j.tagNameCheck instanceof RegExp&&Et(j.tagNameCheck,D)||j.tagNameCheck instanceof Function&&j.tagNameCheck(D))&&(j.attributeNameCheck instanceof RegExp&&Et(j.attributeNameCheck,F)||j.attributeNameCheck instanceof Function&&j.attributeNameCheck(F))||"is"===F&&j.allowCustomizedBuiltInElements&&(j.tagNameCheck instanceof RegExp&&Et(j.tagNameCheck,G)||j.tagNameCheck instanceof Function&&j.tagNameCheck(G))))return!1}else if(!P[F]&&!Et(S,Wo(G,x,""))&&("src"!==F&&"xlink:href"!==F&&"href"!==F||"script"===D||0!==R8(G,"data:")||!jr[D])&&(!bt||Et(B,Wo(G,x,"")))&&G)return!1;return!0},Jg=function(D){return D.indexOf("-")>0},e1=function(D){dn("beforeSanitizeAttributes",D,null);const{attributes:F}=D;if(!F)return;const G={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:k};let Ee=F.length;for(;Ee--;){const Ke=F[Ee],{name:Ye,namespaceURI:lt,value:or}=Ke,aa=Pe(Ye);let ut="value"===Ye?or:L8(or);if(G.attrName=aa,G.attrValue=ut,G.keepAttr=!0,G.forceKeepAttr=void 0,dn("uponSanitizeAttribute",D,G),ut=G.attrValue,G.forceKeepAttr||(Dc(Ye,D),!G.keepAttr))continue;if(!Ut&&Et(/\/>/i,ut)){Dc(Ye,D);continue}At&&Ys([W,le,K],(n1=>{ut=Wo(ut,n1," ")}));const t1=Pe(D.nodeName);if(Qg(t1,aa,ut)){if(Gr&&("id"===aa||"name"===aa)&&(Dc(Ye,D),ut="user-content-"+ut),E&&"object"==typeof f&&"function"==typeof f.getAttributeType&&!lt)switch(f.getAttributeType(t1,aa)){case"TrustedHTML":ut=E.createHTML(ut);break;case"TrustedScriptURL":ut=E.createScriptURL(ut)}try{lt?D.setAttributeNS(lt,Ye,ut):D.setAttribute(Ye,ut),Km(e.removed)}catch{}}}dn("afterSanitizeAttributes",D,null)},oN=function Z(D){let F=null;const G=Kg(D);for(dn("beforeSanitizeShadowDOM",D,null);F=G.nextNode();)dn("uponSanitizeShadowNode",F,null),!Xg(F)&&(F.content instanceof a&&Z(F.content),e1(F));dn("afterSanitizeShadowDOM",D,null)};return e.sanitize=function(Z){let D=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},F=null,G=null,Ee=null,Ke=null;if(na=!Z,na&&(Z="\x3c!--\x3e"),"string"!=typeof Z&&!Yg(Z)){if("function"!=typeof Z.toString)throw Ko("toString is not a function");if("string"!=typeof(Z=Z.toString()))throw Ko("dirty is not a string, aborting")}if(!e.isSupported)return Z;if(xt||yc(D),e.removed=[],"string"==typeof Z&&(Ce=!1),Ce){if(Z.nodeName){const or=Pe(Z.nodeName);if(!C[or]||ge[or])throw Ko("root node is forbidden and cannot be sanitized in-place")}}else if(Z instanceof i)F=Wg("\x3c!----\x3e"),G=F.ownerDocument.importNode(Z,!0),1===G.nodeType&&"BODY"===G.nodeName||"HTML"===G.nodeName?F=G:F.appendChild(G);else{if(!Oe&&!At&&!je&&-1===Z.indexOf("<"))return E&&Ne?E.createHTML(Z):Z;if(F=Wg(Z),!F)return Oe?null:Ne?_:""}F&&ne&&rr(F.firstChild);const Ye=Kg(Ce?Z:F);for(;Ee=Ye.nextNode();)Xg(Ee)||(Ee.content instanceof a&&oN(Ee.content),e1(Ee));if(Ce)return Z;if(Oe){if(Be)for(Ke=T.call(F.ownerDocument);F.firstChild;)Ke.appendChild(F.firstChild);else Ke=F;return(k.shadowroot||k.shadowrootmode)&&(Ke=H.call(r,Ke,!0)),Ke}let lt=je?F.outerHTML:F.innerHTML;return je&&C["!doctype"]&&F.ownerDocument&&F.ownerDocument.doctype&&F.ownerDocument.doctype.name&&Et(tg,F.ownerDocument.doctype.name)&&(lt="\n"+lt),At&&Ys([W,le,K],(or=>{lt=Wo(lt,or," ")})),E&&Ne?E.createHTML(lt):lt},e.setConfig=function(){yc(arguments.length>0&&void 0!==arguments[0]?arguments[0]:{}),xt=!0},e.clearConfig=function(){Kr=null,xt=!1},e.isValidAttribute=function(Z,D,F){Kr||yc({});const G=Pe(Z),Ee=Pe(D);return Qg(G,Ee,F)},e.addHook=function(Z,D){"function"==typeof D&&(I[Z]=I[Z]||[],jo(I[Z],D))},e.removeHook=function(Z){if(I[Z])return Km(I[Z])},e.removeHooks=function(Z){I[Z]&&(I[Z]=[])},e.removeAllHooks=function(){I={}},e}();const og=G8(window);function ag(t){if(!t)return"";try{return new Date(1e3*t).toLocaleTimeString([],{hour:"numeric",minute:"2-digit",hour12:!0})}catch{return""}}og.setConfig({ADD_ATTR:["target","rel"]});const Z8=({thought:t})=>{const[e,n]=U.useState(!1);return t&&ae.settings.showThoughts?w.jsxs("div",{className:"allm-mb-2",children:[w.jsxs("div",{onClick:()=>n(!e),className:"allm-cursor-pointer allm-flex allm-items-center allm-gap-x-1.5 allm-text-gray-400 hover:allm-text-gray-500",children:[w.jsx(vu,{size:14,weight:"bold",className:"allm-transition-transform "+(e?"allm-rotate-180":"")}),w.jsx("span",{className:"allm-text-xs allm-font-medium",children:"View thoughts"})]}),e&&w.jsx("div",{className:"allm-mt-2 allm-mb-3 allm-pl-0 allm-border-l-2 allm-border-gray-200",children:w.jsx("div",{className:"allm-text-xs allm-text-gray-600 allm-font-mono allm-whitespace-pre-wrap",children:t.trim()})})]}):null},j8=U.forwardRef((({uuid:t=Kn(),message:e,role:n,sources:r=[],error:o=!1,errorMsg:a=null,sentAt:s},i)=>{const l=ae.settings.textSize?`allm-text-[${ae.settings.textSize}px]`:"allm-text-sm";o&&console.error(`ANYTHING_LLM_CHAT_WIDGET_ERROR: ${o}`);const c=((null==e?void 0:e.match(/([\s\S]*?)<\/think>/g))||[]).map((d=>d.replace(/|<\/think>/g,"").trim())),p=null==e?void 0:e.replace(/[\s\S]*?<\/think>/g,"").trim();return w.jsxs("div",{className:"allm-py-[5px]",children:["assistant"===n&&w.jsx("div",{className:"allm-text-[10px] allm-text-gray-400 allm-ml-[54px] allm-mr-6 allm-mb-2 allm-text-left allm-font-sans",children:ae.settings.assistantName||"Anything LLM Chat Assistant"}),w.jsxs("div",{ref:i,className:"allm-flex allm-items-start allm-w-full allm-h-fit "+("user"===n?"allm-justify-end":"allm-justify-start"),children:["assistant"===n&&w.jsx("img",{src:ae.settings.assistantIcon||qo,alt:"Anything LLM Icon",className:"allm-w-9 allm-h-9 allm-flex-shrink-0 allm-ml-2",id:"anything-llm-icon"}),w.jsx("div",{style:{wordBreak:"break-word",backgroundColor:"user"===n?ae.USER_STYLES.msgBg:ae.ASSISTANT_STYLES.msgBg},className:`allm-py-[11px] allm-px-4 allm-flex allm-flex-col allm-font-sans ${o?"allm-bg-red-200 allm-rounded-lg allm-mr-[37px] allm-ml-[9px]":"user"===n?`${ae.USER_STYLES.base} allm-anything-llm-user-message`:`${ae.ASSISTANT_STYLES.base} allm-anything-llm-assistant-message`} allm-shadow-[0_4px_14px_rgba(0,0,0,0.25)]`,children:w.jsx("div",{className:"allm-flex allm-flex-col",children:o?w.jsxs("div",{className:"allm-p-2 allm-rounded-lg allm-bg-red-50 allm-text-red-500",children:[w.jsxs("span",{className:"allm-inline-block",children:[w.jsx(yu,{className:"allm-h-4 allm-w-4 allm-mb-1 allm-inline-block"})," ","Could not respond to message."]}),w.jsx("p",{className:"allm-text-xs allm-font-mono allm-mt-2 allm-border-l-2 allm-border-red-500 allm-pl-2 allm-bg-red-300 allm-p-2 allm-rounded-sm",children:a||"Server error"})]}):w.jsxs(w.Fragment,{children:["assistant"===n&&c.length>0&&w.jsx(Z8,{thought:c.join("\n\n")}),w.jsx("span",{className:`allm-whitespace-pre-line allm-flex allm-flex-col allm-gap-y-1 ${l} allm-leading-[20px]`,dangerouslySetInnerHTML:{__html:og.sanitize(Gm(p||e))}})]})})})]},t),s&&w.jsx("div",{className:"allm-font-sans allm-text-[10px] allm-text-gray-400 allm-ml-[54px] allm-mr-6 allm-mt-2 "+("user"===n?"allm-text-right":"allm-text-left"),children:ag(s)})]})})),W8=U.memo(j8),K8=({hasThought:t})=>t?w.jsxs("div",{className:"allm-flex allm-items-center allm-gap-x-2 allm-text-gray-500",children:[w.jsx(Ds,{size:16,className:"allm-animate-spin"}),w.jsx("span",{className:"allm-text-sm",children:"Thinking..."})]}):w.jsx("div",{className:"allm-mx-4 allm-my-1 allm-dot-falling"}),sg=({thought:t})=>{const[e,n]=U.useState(!1);if(!t||!ae.settings.showThoughts)return null;const r=t.replace(/<\/?think>/g,"").trim();return w.jsxs("div",{className:"allm-mb-2",children:[w.jsxs("div",{onClick:()=>n(!e),className:"allm-cursor-pointer allm-flex allm-items-center allm-gap-x-1.5 allm-text-gray-400 hover:allm-text-gray-500",children:[w.jsx(vu,{size:14,weight:"bold",className:"allm-transition-transform "+(e?"allm-rotate-180":"")}),w.jsx("span",{className:"allm-text-xs allm-font-medium",children:"View thoughts"})]}),e&&w.jsx("div",{className:"allm-mt-2 allm-mb-3 allm-pl-0 allm-border-l-2 allm-border-gray-200",children:w.jsx("div",{className:"allm-text-xs allm-text-gray-600 allm-font-mono allm-whitespace-pre-wrap",children:r})})]})},Y8=U.forwardRef((({uuid:t,reply:e,pending:n,error:r,sources:o=[],sentAt:a},s)=>{var f;if(!e&&0===o.length&&!n&&!r)return null;r&&console.error(`ANYTHING_LLM_CHAT_WIDGET_ERROR: ${r}`);const l=((null==e?void 0:e.match(/([\s\S]*?)<\/think>/g))||[]).map((b=>b.replace(/<\/?think>/g,"").trim())),u=(null==e?void 0:e.includes(""))&&!(null!=e&&e.includes("")),c=u?null==(f=null==e?void 0:e.split("").pop())?void 0:f.replace(/<\/?think>/g,"").trim():null;c||l[l.length-1];const p=u||n,d=null==e?void 0:e.replace(/[\s\S]*?<\/think>/g,"").replace(/.*$/g,"").replace(/<\/?think>/g,"").trim();return p?w.jsxs("div",{className:"allm-py-[5px]",children:[w.jsx("div",{className:"allm-text-[10px] allm-text-gray-400 allm-ml-[54px] allm-mr-6 allm-mb-2 allm-text-left allm-font-sans",children:ae.settings.assistantName||"Anything LLM Chat Assistant"}),w.jsxs("div",{className:"allm-flex allm-items-start allm-w-full allm-h-fit allm-justify-start",children:[w.jsx("img",{src:ae.settings.assistantIcon||qo,alt:"Anything LLM Icon",className:"allm-w-9 allm-h-9 allm-flex-shrink-0 allm-ml-2"}),w.jsxs("div",{style:{wordBreak:"break-word",backgroundColor:ae.ASSISTANT_STYLES.msgBg},className:`allm-py-[11px] allm-px-4 allm-flex allm-flex-col ${ae.ASSISTANT_STYLES.base} allm-shadow-[0_4px_14px_rgba(0,0,0,0.25)]`,children:[u&&c&&w.jsx(sg,{thought:c}),w.jsx(K8,{hasThought:u})]})]})]}):r?w.jsxs("div",{className:"allm-py-[5px]",children:[w.jsx("div",{className:"allm-text-[10px] allm-text-gray-400 allm-ml-[54px] allm-mr-6 allm-mb-2 allm-text-left allm-font-sans",children:ae.settings.assistantName||"Anything LLM Chat Assistant"}),w.jsxs("div",{className:"allm-flex allm-items-start allm-w-full allm-h-fit allm-justify-start",children:[w.jsx("img",{src:ae.settings.assistantIcon||qo,alt:"Anything LLM Icon",className:"allm-w-9 allm-h-9 allm-flex-shrink-0 allm-ml-2"}),w.jsx("div",{className:"allm-py-[11px] allm-px-4 allm-rounded-lg allm-flex allm-flex-col allm-bg-red-200 allm-shadow-[0_4px_14px_rgba(0,0,0,0.25)] allm-mr-[37px] allm-ml-[9px]",children:w.jsx("div",{className:"allm-flex allm-gap-x-5",children:w.jsxs("span",{className:"allm-inline-block allm-p-2 allm-rounded-lg allm-bg-red-50 allm-text-red-500",children:[w.jsx(yu,{className:"allm-h-4 allm-w-4 allm-mb-1 allm-inline-block"})," ","Could not respond to message.",w.jsx("span",{className:"allm-text-xs",children:"Server error"})]})})})]})]}):w.jsxs("div",{className:"allm-py-[5px]",children:[w.jsx("div",{className:"allm-text-[10px] allm-text-gray-400 allm-ml-[54px] allm-mr-6 allm-mb-2 allm-text-left allm-font-sans",children:ae.settings.assistantName||"Anything LLM Chat Assistant"}),w.jsxs("div",{ref:s,className:"allm-flex allm-items-start allm-w-full allm-h-fit allm-justify-start",children:[w.jsx("img",{src:ae.settings.assistantIcon||qo,alt:"Anything LLM Icon",className:"allm-w-9 allm-h-9 allm-flex-shrink-0 allm-ml-2"}),w.jsxs("div",{style:{wordBreak:"break-word",backgroundColor:ae.ASSISTANT_STYLES.msgBg},className:`allm-py-[11px] allm-px-4 allm-flex allm-flex-col ${ae.ASSISTANT_STYLES.base} allm-shadow-[0_4px_14px_rgba(0,0,0,0.25)]`,children:[l.length>0&&w.jsx(sg,{thought:l.join("\n\n")}),w.jsx("div",{className:"allm-flex allm-gap-x-5",children:w.jsx("span",{className:"allm-font-sans allm-reply allm-whitespace-pre-line allm-font-normal allm-text-sm allm-md:text-sm allm-flex allm-flex-col allm-gap-y-1",dangerouslySetInnerHTML:{__html:Gm(d||"")}})})]})]},t),a&&w.jsx("div",{className:"allm-text-[10px] allm-text-gray-400 allm-ml-[54px] allm-mr-6 allm-mt-2 allm-text-left allm-font-sans",children:ag(a)})]})})),X8=U.memo(Y8);var ig=NaN,J8="[object Symbol]",eC=/^\s+|\s+$/g,tC=/^[-+]0x[0-9a-f]+$/i,nC=/^0b[01]+$/i,rC=/^0o[0-7]+$/i,oC=parseInt,aC="object"==typeof xe&&xe&&xe.Object===Object&&xe,sC="object"==typeof self&&self&&self.Object===Object&&self,iC=aC||sC||Function("return this")(),uC=Object.prototype.toString,cC=Math.max,dC=Math.min,mc=function(){return iC.Date.now()};function gc(t){var e=typeof t;return!!t&&("object"==e||"function"==e)}function lg(t){if("number"==typeof t)return t;if(function(t){return"symbol"==typeof t||function(t){return!!t&&"object"==typeof t}(t)&&uC.call(t)==J8}(t))return ig;if(gc(t)){var e="function"==typeof t.valueOf?t.valueOf():t;t=gc(e)?e+"":e}if("string"!=typeof t)return 0===t?t:+t;t=t.replace(eC,"");var n=nC.test(t);return n||rC.test(t)?oC(t.slice(2),n?2:8):tC.test(t)?ig:+t}var gC=function(t,e,n){var r,o,a,s,i,l,u=0,c=!1,p=!1,d=!0;if("function"!=typeof t)throw new TypeError("Expected a function");function f(v){var T=r,R=o;return r=o=void 0,u=v,s=t.apply(R,T)}function y(v){var T=v-l;return void 0===l||T>=e||T<0||p&&v-u>=a}function h(){var v=mc();if(y(v))return g(v);i=setTimeout(h,function(v){var H=e-(v-l);return p?dC(H,a-(v-u)):H}(v))}function g(v){return i=void 0,d&&r?f(v):(r=o=void 0,s)}function N(){var v=mc(),T=y(v);if(r=arguments,o=this,l=v,T){if(void 0===i)return function(v){return u=v,i=setTimeout(h,e),c?f(v):s}(l);if(p)return i=setTimeout(h,e),f(l)}return void 0===i&&(i=setTimeout(h,e)),s}return e=lg(e)||0,gc(n)&&(c=!!n.leading,a=(p="maxWait"in n)?cC(lg(n.maxWait)||0,e):a,d="trailing"in n?!!n.trailing:d),N.cancel=function(){void 0!==i&&clearTimeout(i),u=0,r=l=o=i=void 0},N.flush=function(){return void 0===i?s:g(mc())},N};const hC=Ht(gC);function EC({settings:t={},history:e=[]}){const n=U.useRef(null),[r,o]=U.useState(!0),a=U.useRef(null);U.useEffect((()=>{l()}),[e]);const i=hC((()=>{if(!a.current)return;const c=a.current.scrollHeight-a.current.scrollTop-a.current.clientHeight<=40;o(c)}),100);U.useEffect((()=>{!function(){if(!a.current)return null;const c=a.current;if(!c)return null;c.addEventListener("scroll",i)}()}),[]);const l=()=>{a.current&&a.current.scrollTo({top:a.current.scrollHeight,behavior:"smooth"})};return 0===e.length?w.jsx("div",{className:"allm-h-full allm-overflow-y-auto allm-px-2 allm-py-4 allm-flex allm-flex-col allm-justify-start allm-no-scroll",children:w.jsxs("div",{className:"allm-flex allm-h-full allm-flex-col allm-items-center allm-justify-center",children:[w.jsx("p",{className:"allm-text-slate-400 allm-text-sm allm-font-sans allm-py-4 allm-text-center",children:(null==t?void 0:t.greeting)??"Send a chat to get started."}),w.jsx(AC,{settings:t})]})}):w.jsxs("div",{className:"allm-h-full allm-overflow-y-auto allm-px-2 allm-pt-4 allm-pb-8 allm-flex allm-flex-col allm-justify-start allm-no-scroll",id:"chat-history",ref:a,children:[w.jsx("div",{className:"allm-flex allm-flex-col allm-gap-y-4",children:e.map(((u,c)=>{const p=c===e.length-1;return c===e.length-1&&"assistant"===u.role&&u.animate?w.jsx(X8,{ref:p?n:null,uuid:u.uuid,reply:u.content,pending:u.pending,sources:u.sources,error:u.error,closed:u.closed},u.uuid):w.jsx(W8,{ref:p?n:null,message:u.content,sentAt:u.sentAt||Date.now()/1e3,role:u.role,sources:u.sources,chatId:u.chatId,feedbackScore:u.feedbackScore,error:u.error,errorMsg:u.errorMsg},c)}))}),!r&&w.jsx("div",{className:"allm-fixed allm-bottom-[10rem] allm-right-[50px] allm-z-50 allm-cursor-pointer allm-animate-pulse",children:w.jsx("div",{className:"allm-flex allm-flex-col allm-items-center",children:w.jsx("div",{className:"allm-rounded-full allm-border allm-border-white/10 allm-bg-black/20 hover:allm-bg-black/50 allm-w-8 allm-h-8 allm-flex allm-items-center allm-justify-center",children:w.jsx(sf,{weight:"bold",className:"allm-text-white/50 allm-w-4 allm-h-4",onClick:l,id:"scroll-to-bottom-button","aria-label":"Scroll to bottom"})})})})]})}function bC(){return w.jsx("div",{className:"allm-h-full allm-w-full allm-relative",children:w.jsx("div",{className:"allm-h-full allm-max-h-[82vh] allm-pb-[100px] allm-pt-[5px] allm-bg-gray-100 allm-rounded-lg allm-px-2 allm-h-full allm-mt-2 allm-gap-y-2 allm-overflow-y-scroll allm-flex allm-flex-col allm-justify-start allm-no-scroll",children:w.jsx("div",{className:"allm-flex allm-h-full allm-flex-col allm-items-center allm-justify-center",children:w.jsx(Ds,{size:14,className:"allm-text-slate-400 allm-animate-spin"})})})})}function AC({settings:t}){var e;return null!=(e=null==t?void 0:t.defaultMessages)&&e.length?w.jsx("div",{className:"allm-flex allm-flex-col allm-gap-y-2 allm-w-[75%]",children:t.defaultMessages.map(((n,r)=>w.jsx("button",{style:{opacity:0,wordBreak:"break-word",backgroundColor:ae.USER_STYLES.msgBg,fontSize:t.textSize},type:"button",onClick:()=>{window.dispatchEvent(new CustomEvent(bc,{detail:{command:n}}))},className:"msg-suggestion allm-border-none hover:allm-shadow-[0_4px_14px_rgba(0,0,0,0.5)] allm-cursor-pointer allm-px-2 allm-py-2 allm-rounded-lg allm-text-white allm-w-full allm-shadow-[0_4px_14px_rgba(0,0,0,0.25)]",children:n},r)))}):null}const ug={};function hc(){for(var t=arguments.length,e=new Array(t),n=0;n()=>{if(t.isInitialized)e();else{const n=()=>{setTimeout((()=>{t.off("initialized",n)}),0),e()};t.on("initialized",n)}},dg=(t,e,n)=>{t.loadNamespaces(e,cg(t,n))},pg=(t,e,n,r)=>{nr(n)&&(n=[n]),n.forEach((o=>{t.options.ns.indexOf(o)<0&&t.options.ns.push(o)})),t.loadLanguages(e,cg(t,r))},nr=t=>"string"==typeof t,CC=/&(?:amp|#38|lt|#60|gt|#62|apos|#39|quot|#34|nbsp|#160|copy|#169|reg|#174|hellip|#8230|#x2F|#47);/g,SC={"&":"&","&":"&","<":"<","<":"<",">":">",">":">","'":"'","'":"'",""":'"',""":'"'," ":" "," ":" ","©":"©","©":"©","®":"®","®":"®","…":"…","…":"…","/":"/","/":"/"},NC=t=>SC[t];let Ec={bindI18n:"languageChanged",bindI18nStore:"",transEmptyNodeValue:"",transSupportBasicHtmlNodes:!0,transWrapTextNodes:"",transKeepBasicHtmlNodesFor:["br","strong","i","p"],useSuspense:!0,unescape:t=>t.replace(CC,NC)};let fg;const LC={type:"3rdParty",init(t){(function(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};Ec={...Ec,...t}})(t.options.react),(t=>{fg=t})(t)}},mg=U.createContext();class OC{constructor(){r1(this,"getUsedNamespaces",(()=>Object.keys(this.usedNamespaces))),this.usedNamespaces={}}addUsedNamespaces(e){e.forEach((n=>{this.usedNamespaces[n]||(this.usedNamespaces[n]=!0)}))}}const gg=(t,e,n,r)=>t.getFixedT(e,n,r),hg=function(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const{i18n:n}=e,{i18n:r,defaultNS:o}=U.useContext(mg)||{},a=n||r||fg;if(a&&!a.reportNamespaces&&(a.reportNamespaces=new OC),!a){hc("You will need to pass in an i18next instance by using initReactI18next");const _=(v,T)=>nr(T)?T:(t=>"object"==typeof t&&null!==t)(T)&&nr(T.defaultValue)?T.defaultValue:Array.isArray(v)?v[v.length-1]:v,N=[_,{},!1];return N.t=_,N.i18n={},N.ready=!1,N}a.options.react&&void 0!==a.options.react.wait&&hc("It seems you are still using the old wait option, you may migrate to the new useSuspense behaviour.");const s={...Ec,...a.options.react,...e},{useSuspense:i,keyPrefix:l}=s;let u=t||o||a.options&&a.options.defaultNS;u=nr(u)?[u]:u||["translation"],a.reportNamespaces.addUsedNamespaces&&a.reportNamespaces.addUsedNamespaces(u);const c=(a.isInitialized||a.initializedStoreOnce)&&u.every((_=>function(t,e){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return e.languages&&e.languages.length?void 0!==e.options.ignoreJSONStructure?e.hasLoadedNamespace(t,{lng:n.lng,precheck:(o,a)=>{if(n.bindI18n&&n.bindI18n.indexOf("languageChanging")>-1&&o.services.backendConnector.backend&&o.isLanguageChangingTo&&!a(o.isLanguageChangingTo,t))return!1}}):function(t,e){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const r=e.languages[0],o=!!e.options&&e.options.fallbackLng,a=e.languages[e.languages.length-1];if("cimode"===r.toLowerCase())return!0;const s=(i,l)=>{const u=e.services.backendConnector.state[`${i}|${l}`];return-1===u||2===u};return!(n.bindI18n&&n.bindI18n.indexOf("languageChanging")>-1&&e.services.backendConnector.backend&&e.isLanguageChangingTo&&!s(e.isLanguageChangingTo,t)||!(e.hasResourceBundle(r,t)||!e.services.backendConnector.backend||e.options.resources&&!e.options.partialBundledLanguages||s(r,t)&&(!o||s(a,t))))}(t,e,n):(hc("i18n.languages were undefined or empty",e.languages),!0)}(_,a,s))),p=((t,e,n,r)=>U.useCallback(gg(t,e,n,r),[t,e,n,r]))(a,e.lng||null,"fallback"===s.nsMode?u:u[0],l),d=()=>p,f=()=>gg(a,e.lng||null,"fallback"===s.nsMode?u:u[0],l),[b,A]=U.useState(d);let y=u.join();e.lng&&(y=`${e.lng}${y}`);const h=((t,e)=>{const n=U.useRef();return U.useEffect((()=>{n.current=e?n.current:t}),[t,e]),n.current})(y),g=U.useRef(!0);U.useEffect((()=>{const{bindI18n:_,bindI18nStore:N}=s;g.current=!0,!c&&!i&&(e.lng?pg(a,e.lng,u,(()=>{g.current&&A(f)})):dg(a,u,(()=>{g.current&&A(f)}))),c&&h&&h!==y&&g.current&&A(f);const v=()=>{g.current&&A(f)};return _&&a&&a.on(_,v),N&&a&&a.store.on(N,v),()=>{g.current=!1,_&&a&&_.split(" ").forEach((T=>a.off(T,v))),N&&a&&N.split(" ").forEach((T=>a.store.off(T,v)))}}),[a,y]),U.useEffect((()=>{g.current&&c&&A(d)}),[a,l,c]);const E=[b,a,c];if(E.t=b,E.i18n=a,E.ready=c,c||!c&&!i)return E;throw new Promise((_=>{e.lng?pg(a,e.lng,u,(()=>_())):dg(a,u,(()=>_()))}))};function MC(t){let{i18n:e,defaultNS:n,children:r}=t;const o=U.useMemo((()=>({i18n:e,defaultNS:n})),[e,n]);return U.createElement(mg.Provider,{value:o},r)}function FC({settings:t,message:e,submit:n,onChange:r,inputDisabled:o,buttonDisabled:a}){const{t:s}=hg(),i=U.useRef(null),l=U.useRef(null),[u,c]=U.useState(!1);U.useEffect((()=>{!o&&l.current&&l.current.focus(),d()}),[o]);const d=()=>{l.current&&(l.current.style.height="auto")},b=A=>{const y=A.target;y.style.height="auto",y.style.height=0!==A.target.value.length?y.scrollHeight+"px":"auto"};return w.jsx("div",{className:"allm-w-full allm-sticky allm-bottom-0 allm-z-10 allm-flex allm-justify-center allm-items-center allm-bg-white",children:w.jsx("form",{onSubmit:A=>{c(!1),n(A)},className:"allm-flex allm-flex-col allm-gap-y-1 allm-rounded-t-lg allm-w-full allm-items-center allm-justify-center",children:w.jsx("div",{className:"allm-flex allm-items-center allm-w-full",children:w.jsx("div",{className:"allm-bg-white allm-flex allm-flex-col allm-px-4 allm-overflow-hidden allm-w-full",children:w.jsxs("div",{style:{border:"1.5px solid #22262833"},className:"allm-flex allm-items-center allm-w-full allm-rounded-2xl",children:[w.jsx("textarea",{ref:l,onKeyUp:b,onKeyDown:A=>{13==A.keyCode&&(A.shiftKey||n(A))},onChange:r,required:!0,disabled:o,onFocus:()=>c(!0),onBlur:A=>{c(!1),b(A)},value:e,className:"allm-font-sans allm-border-none allm-cursor-text allm-max-h-[100px] allm-text-[14px] allm-mx-2 allm-py-2 allm-w-full allm-text-black allm-bg-transparent placeholder:allm-text-slate-800/60 allm-resize-none active:allm-outline-none focus:allm-outline-none allm-flex-grow",placeholder:t.sendMessageText||s("chat.send-message"),id:"message-input"}),w.jsxs("button",{ref:i,type:"submit",disabled:a,className:"allm-bg-transparent allm-border-none allm-inline-flex allm-justify-center allm-rounded-2xl allm-cursor-pointer allm-text-black group",id:"send-message-button","aria-label":"Send message",children:[a?w.jsx(Ds,{className:"allm-w-4 allm-h-4 allm-animate-spin"}):w.jsx(Hf,{size:24,className:"allm-my-3 allm-text-[#22262899]/60 group-hover:allm-text-[#22262899]/90",weight:"fill"}),w.jsx("span",{className:"allm-sr-only",children:"Send message"})]})]})})})})})}const bc="anythingllm-embed-send-prompt";function PC({sessionId:t,settings:e,knownHistory:n=[]}){const[r,o]=U.useState(""),[a,s]=U.useState(!1),[i,l]=U.useState(n);U.useEffect((()=>{n.length!==i.length&&l([...n])}),[n]);U.useEffect((()=>{!0===a&&async function(){const b=i.length>0?i[i.length-1]:null,A=i.length>0?i.slice(0,-1):[];var y=[...A];if(!b||null==b||!b.userMessage)return s(!1),!1;await Cs.streamChat(t,e,b.userMessage,(h=>function(t,e,n,r,o){const{uuid:a,textResponse:s,type:i,sources:l=[],error:u,close:c,errorMsg:p=null}=t,d=o[o.length-1],f=null==d?void 0:d.sentAt;if("abort"===i)e(!1),n([...r,{uuid:a,content:s,role:"assistant",sources:l,closed:!0,error:u,errorMsg:p,animate:!1,pending:!1,sentAt:f}]),o.push({uuid:a,content:s,role:"assistant",sources:l,closed:!0,error:u,errorMsg:p,animate:!1,pending:!1,sentAt:f});else if("textResponse"===i)e(!1),n([...r,{uuid:a,content:s,role:"assistant",sources:l,closed:c,error:u,errorMsg:p,animate:!c,pending:!1,sentAt:f}]),o.push({uuid:a,content:s,role:"assistant",sources:l,closed:c,error:u,errorMsg:p,animate:!c,pending:!1,sentAt:f});else if("textResponseChunk"===i){const b=o.findIndex((A=>A.uuid===a));if(-1!==b){const A={...o[b]},y={...A,content:A.content+s,sources:l,error:u,errorMsg:p,closed:c,animate:!c,pending:!1,sentAt:f};o[b]=y}else o.push({uuid:a,sources:l,error:u,errorMsg:p,content:s,role:"assistant",closed:c,animate:!c,pending:!1,sentAt:f});n([...o])}}(h,s,l,A,y)))}()}),[a,i]);const d=f=>{f.detail.command&&((f,b=[],A=[])=>{if(!f||""===f)return!1;let y;y=b.length>0?[...b,{content:"",role:"assistant",pending:!0,userMessage:f,attachments:A,animate:!0}]:[...i,{content:f,role:"user",attachments:A},{content:"",role:"assistant",pending:!0,userMessage:f,animate:!0}],l(y),s(!0)})(f.detail.command,[],[])};return U.useEffect((()=>(window.addEventListener(bc,d),()=>{window.removeEventListener(bc,d)})),[]),w.jsxs("div",{className:"allm-h-full allm-w-full allm-flex allm-flex-col",children:[w.jsx("div",{className:"allm-flex-1 allm-min-h-0 allm-mb-8",children:w.jsx(EC,{settings:e,history:i})}),w.jsx("div",{className:"allm-flex-shrink-0 allm-mt-auto",children:w.jsx(FC,{settings:e,message:r,submit:async f=>{if(f.preventDefault(),!r||""===r)return!1;const b=[...i,{content:r,role:"user",sentAt:Math.floor(Date.now()/1e3)},{content:"",role:"assistant",pending:!0,userMessage:r,animate:!0,sentAt:Math.floor(Date.now()/1e3)}];l(b),o(""),s(!0)},onChange:f=>{o(f.target.value)},inputDisabled:a,buttonDisabled:a})})]})}function Eg({settings:t}){return t.noSponsor?null:w.jsx("div",{className:"allm-flex allm-w-full allm-items-center allm-justify-center",children:w.jsx("a",{style:{color:"#0119D9"},href:t.sponsorLink??"#",target:"_blank",rel:"noreferrer",className:"allm-text-xs allm-font-sans hover:allm-opacity-80 hover:allm-underline",children:t.sponsorText})})}function UC({setChatHistory:t,settings:e,sessionId:n,closeChat:r}){const{t:o}=hg();return w.jsxs("div",{className:"allm-w-full allm-flex allm-justify-center allm-gap-x-1 p-0",children:[w.jsx("button",{style:{color:"#7A7D7E"},className:"allm-h-fit allm-px-0 hover:allm-cursor-pointer allm-border-none allm-text-sm allm-bg-transparent hover:allm-opacity-80 hover:allm-underline",onClick:()=>(async()=>{await Cs.resetEmbedChatSession(e,n),t([])})(),children:e.resetChatText||o("chat.reset-chat")}),e.noHeader&&w.jsxs(w.Fragment,{children:[w.jsx("p",{className:"allm-m-0 allm-h-fit allm-text-sm allm-text-[#7A7D7E]",children:"|"}),w.jsx("button",{type:"button",style:{color:"#7A7D7E"},className:"allm-h-fit allm-px-0 hover:allm-cursor-pointer allm-border-none allm-text-sm allm-bg-transparent hover:allm-opacity-80 hover:allm-underline",onClick:r,children:"Close Chat"})]})]})}function qC({closeChat:t,settings:e,sessionId:n}){const{chatHistory:r,setChatHistory:o,loading:a}=function(t=null,e=null){const[n,r]=U.useState(!0),[o,a]=U.useState([]);return U.useEffect((()=>{!async function(){if(e&&t)try{const i=await Cs.embedSessionHistory(t,e);a(i),r(!1)}catch(i){console.error("Error fetching historical chats:",i),r(!1)}}()}),[e,t]),{chatHistory:o,setChatHistory:a,loading:n}}(e,n);return a?w.jsxs("div",{className:"allm-flex allm-flex-col allm-h-full",children:[w.jsx(Qf,{sessionId:n,settings:e,iconUrl:e.brandImageUrl,closeChat:t,setChatHistory:o}),w.jsx(bC,{}),w.jsxs("div",{className:"allm-pt-4 allm-pb-2 allm-h-fit allm-gap-y-1",children:[w.jsx(w_,{}),w.jsx(Eg,{settings:e})]})]}):(null==document||document.addEventListener("click",(function(t){var r;const e=t.target.closest("[data-code-snippet]"),n=null==(r=null==e?void 0:e.dataset)?void 0:r.code;if(!n)return!1;!function(t){var o,a,s;const e=document.querySelector(`[data-code="${t}"]`);if(!e)return!1;const n=null==(s=null==(a=null==(o=e.parentElement)?void 0:o.parentElement)?void 0:a.querySelector("pre:first-of-type"))?void 0:s.innerText;if(!n)return!1;window.navigator.clipboard.writeText(n),e.classList.add("allm-text-green-500");const r=e.innerHTML;e.innerText="Copied!",e.setAttribute("disabled",!0),setTimeout((()=>{e.classList.remove("allm-text-green-500"),e.innerHTML=r,e.removeAttribute("disabled")}),2500)}(n)})),w.jsxs("div",{className:"allm-flex allm-flex-col allm-h-full",children:[!e.noHeader&&w.jsx(Qf,{sessionId:n,settings:e,iconUrl:e.brandImageUrl,closeChat:t,setChatHistory:o}),w.jsx("div",{className:"allm-flex-grow allm-overflow-y-auto",children:w.jsx(PC,{sessionId:n,settings:e,knownHistory:r})}),w.jsxs("div",{className:"allm-mt-4 allm-pb-4 allm-h-fit allm-gap-y-2 allm-z-10",children:[w.jsx(Eg,{settings:e}),w.jsx(UC,{setChatHistory:o,settings:e,sessionId:n,closeChat:t})]})]}))}const Y=t=>"string"==typeof t,Yo=()=>{let t,e;const n=new Promise(((r,o)=>{t=r,e=o}));return n.resolve=t,n.reject=e,n},bg=t=>null==t?"":""+t,zC=/###/g,Ag=t=>t&&t.indexOf("###")>-1?t.replace(zC,"."):t,_g=t=>!t||Y(t),Xo=(t,e,n)=>{const r=Y(e)?e.split("."):e;let o=0;for(;o{const{obj:r,k:o}=Xo(t,e,Object);if(void 0!==r||1===e.length)return void(r[o]=n);let a=e[e.length-1],s=e.slice(0,e.length-1),i=Xo(t,s,Object);for(;void 0===i.obj&&s.length;)a=`${s[s.length-1]}.${a}`,s=s.slice(0,s.length-1),i=Xo(t,s,Object),i&&i.obj&&typeof i.obj[`${i.k}.${a}`]<"u"&&(i.obj=void 0);i.obj[`${i.k}.${a}`]=n},ei=(t,e)=>{const{obj:n,k:r}=Xo(t,e);if(n)return n[r]},yg=(t,e,n)=>{for(const r in e)"__proto__"!==r&&"constructor"!==r&&(r in t?Y(t[r])||t[r]instanceof String||Y(e[r])||e[r]instanceof String?n&&(t[r]=e[r]):yg(t[r],e[r],n):t[r]=e[r]);return t},$r=t=>t.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&");var jC={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"};const WC=t=>Y(t)?t.replace(/[&<>"'\/]/g,(e=>jC[e])):t;const YC=[" ",",","?","!",";"],XC=new class{constructor(e){this.capacity=e,this.regExpMap=new Map,this.regExpQueue=[]}getRegExp(e){const n=this.regExpMap.get(e);if(void 0!==n)return n;const r=new RegExp(e);return this.regExpQueue.length===this.capacity&&this.regExpMap.delete(this.regExpQueue.shift()),this.regExpMap.set(e,r),this.regExpQueue.push(e),r}}(20),Ac=function(t,e){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:".";if(!t)return;if(t[e])return t[e];const r=e.split(n);let o=t;for(let a=0;a-1&&lt&&t.replace("_","-"),JC={type:"logger",log(t){this.output("log",t)},warn(t){this.output("warn",t)},error(t){this.output("error",t)},output(t,e){console&&console[t]&&console[t].apply(console,e)}};class ni{constructor(e){let n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};this.init(e,n)}init(e){let n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};this.prefix=n.prefix||"i18next:",this.logger=e||JC,this.options=n,this.debug=n.debug}log(){for(var e=arguments.length,n=new Array(e),r=0;r{this.observers[r]||(this.observers[r]=new Map);const o=this.observers[r].get(n)||0;this.observers[r].set(n,o+1)})),this}off(e,n){if(this.observers[e]){if(!n)return void delete this.observers[e];this.observers[e].delete(n)}}emit(e){for(var n=arguments.length,r=new Array(n>1?n-1:0),o=1;o{let[i,l]=s;for(let u=0;u{let[i,l]=s;for(let u=0;u1&&void 0!==arguments[1]?arguments[1]:{ns:["translation"],defaultNS:"translation"};super(),this.data=e||{},this.options=n,void 0===this.options.keySeparator&&(this.options.keySeparator="."),void 0===this.options.ignoreJSONStructure&&(this.options.ignoreJSONStructure=!0)}addNamespaces(e){this.options.ns.indexOf(e)<0&&this.options.ns.push(e)}removeNamespaces(e){const n=this.options.ns.indexOf(e);n>-1&&this.options.ns.splice(n,1)}getResource(e,n,r){let o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};const a=void 0!==o.keySeparator?o.keySeparator:this.options.keySeparator,s=void 0!==o.ignoreJSONStructure?o.ignoreJSONStructure:this.options.ignoreJSONStructure;let i;e.indexOf(".")>-1?i=e.split("."):(i=[e,n],r&&(Array.isArray(r)?i.push(...r):Y(r)&&a?i.push(...r.split(a)):i.push(r)));const l=ei(this.data,i);return!l&&!n&&!r&&e.indexOf(".")>-1&&(e=i[0],n=i[1],r=i.slice(2).join(".")),!l&&s&&Y(r)?Ac(this.data&&this.data[e]&&this.data[e][n],r,a):l}addResource(e,n,r,o){let a=arguments.length>4&&void 0!==arguments[4]?arguments[4]:{silent:!1};const s=void 0!==a.keySeparator?a.keySeparator:this.options.keySeparator;let i=[e,n];r&&(i=i.concat(s?r.split(s):r)),e.indexOf(".")>-1&&(i=e.split("."),o=n,n=i[1]),this.addNamespaces(n),vg(this.data,i,o),a.silent||this.emit("added",e,n,r,o)}addResources(e,n,r){let o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{silent:!1};for(const a in r)(Y(r[a])||Array.isArray(r[a]))&&this.addResource(e,n,a,r[a],{silent:!0});o.silent||this.emit("added",e,n,r)}addResourceBundle(e,n,r,o,a){let s=arguments.length>5&&void 0!==arguments[5]?arguments[5]:{silent:!1,skipCopy:!1},i=[e,n];e.indexOf(".")>-1&&(i=e.split("."),o=r,r=n,n=i[1]),this.addNamespaces(n);let l=ei(this.data,i)||{};s.skipCopy||(r=JSON.parse(JSON.stringify(r))),o?yg(l,r,a):l={...l,...r},vg(this.data,i,l),s.silent||this.emit("added",e,n,r)}removeResourceBundle(e,n){this.hasResourceBundle(e,n)&&delete this.data[e][n],this.removeNamespaces(n),this.emit("removed",e,n)}hasResourceBundle(e,n){return void 0!==this.getResource(e,n)}getResourceBundle(e,n){return n||(n=this.options.defaultNS),"v1"===this.options.compatibilityAPI?{...this.getResource(e,n)}:this.getResource(e,n)}getDataByLanguage(e){return this.data[e]}hasLanguageSomeTranslations(e){const n=this.getDataByLanguage(e);return!!(n&&Object.keys(n)||[]).find((o=>n[o]&&Object.keys(n[o]).length>0))}toJSON(){return this.data}}var Cg={processors:{},addPostProcessor(t){this.processors[t.name]=t},handle(t,e,n,r,o){return t.forEach((a=>{this.processors[a]&&(e=this.processors[a].process(e,n,r,o))})),e}};const Sg={};class oi extends ri{constructor(e){let n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};super(),((t,e,n)=>{t.forEach((r=>{e[r]&&(n[r]=e[r])}))})(["resourceStore","languageUtils","pluralResolver","interpolator","backendConnector","i18nFormat","utils"],e,this),this.options=n,void 0===this.options.keySeparator&&(this.options.keySeparator="."),this.logger=Xt.create("translator")}changeLanguage(e){e&&(this.language=e)}exists(e){let n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{interpolation:{}};if(null==e)return!1;const r=this.resolve(e,n);return r&&void 0!==r.res}extractFromKey(e,n){let r=void 0!==n.nsSeparator?n.nsSeparator:this.options.nsSeparator;void 0===r&&(r=":");const o=void 0!==n.keySeparator?n.keySeparator:this.options.keySeparator;let a=n.ns||this.options.defaultNS||[];const s=r&&e.indexOf(r)>-1,i=!(this.options.userDefinedKeySeparator||n.keySeparator||this.options.userDefinedNsSeparator||n.nsSeparator||((t,e,n)=>{e=e||"",n=n||"";const r=YC.filter((s=>e.indexOf(s)<0&&n.indexOf(s)<0));if(0===r.length)return!0;const o=XC.getRegExp(`(${r.map((s=>"?"===s?"\\?":s)).join("|")})`);let a=!o.test(t);if(!a){const s=t.indexOf(n);s>0&&!o.test(t.substring(0,s))&&(a=!0)}return a})(e,r,o));if(s&&!i){const l=e.match(this.interpolator.nestingRegexp);if(l&&l.length>0)return{key:e,namespaces:Y(a)?[a]:a};const u=e.split(r);(r!==o||r===o&&this.options.ns.indexOf(u[0])>-1)&&(a=u.shift()),e=u.join(o)}return{key:e,namespaces:Y(a)?[a]:a}}translate(e,n,r){if("object"!=typeof n&&this.options.overloadTranslationOptionHandler&&(n=this.options.overloadTranslationOptionHandler(arguments)),"object"==typeof n&&(n={...n}),n||(n={}),null==e)return"";Array.isArray(e)||(e=[String(e)]);const o=void 0!==n.returnDetails?n.returnDetails:this.options.returnDetails,a=void 0!==n.keySeparator?n.keySeparator:this.options.keySeparator,{key:s,namespaces:i}=this.extractFromKey(e[e.length-1],n),l=i[i.length-1],u=n.lng||this.language,c=n.appendNamespaceToCIMode||this.options.appendNamespaceToCIMode;if(u&&"cimode"===u.toLowerCase()){if(c){const _=n.nsSeparator||this.options.nsSeparator;return o?{res:`${l}${_}${s}`,usedKey:s,exactUsedKey:s,usedLng:u,usedNS:l,usedParams:this.getUsedParamsDetails(n)}:`${l}${_}${s}`}return o?{res:s,usedKey:s,exactUsedKey:s,usedLng:u,usedNS:l,usedParams:this.getUsedParamsDetails(n)}:s}const p=this.resolve(e,n);let d=p&&p.res;const f=p&&p.usedKey||s,b=p&&p.exactUsedKey||s,A=Object.prototype.toString.apply(d),h=void 0!==n.joinArrays?n.joinArrays:this.options.joinArrays,g=!this.i18nFormat||this.i18nFormat.handleAsObject,E=!Y(d)&&"boolean"!=typeof d&&"number"!=typeof d;if(!(g&&d&&E&&["[object Number]","[object Function]","[object RegExp]"].indexOf(A)<0)||Y(h)&&Array.isArray(d))if(g&&Y(h)&&Array.isArray(d))d=d.join(h),d&&(d=this.extendTranslation(d,e,n,r));else{let _=!1,N=!1;const v=void 0!==n.count&&!Y(n.count),T=oi.hasDefaultValue(n),R=v?this.pluralResolver.getSuffix(u,n.count,n):"",H=n.ordinal&&v?this.pluralResolver.getSuffix(u,n.count,{ordinal:!1}):"",I=v&&!n.ordinal&&0===n.count&&this.pluralResolver.shouldUseIntlApi(),W=I&&n[`defaultValue${this.options.pluralSeparator}zero`]||n[`defaultValue${R}`]||n[`defaultValue${H}`]||n.defaultValue;!this.isValidLookup(d)&&T&&(_=!0,d=W),this.isValidLookup(d)||(N=!0,d=s);const K=(n.missingKeyNoValueFallbackToKey||this.options.missingKeyNoValueFallbackToKey)&&N?void 0:d,O=T&&W!==d&&this.options.updateMissing;if(N||_||O){if(this.logger.log(O?"updateKey":"missingKey",u,l,s,O?W:d),a){const S=this.resolve(s,{...n,keySeparator:!1});S&&S.res&&this.logger.warn("Seems the loaded translations were in flat JSON format instead of nested. Either set keySeparator: false on init or make sure your translations are published in nested format.")}let V=[];const B=this.languageUtils.getFallbackCodes(this.options.fallbackLng,n.lng||this.language);if("fallback"===this.options.saveMissingTo&&B&&B[0])for(let S=0;S{const k=T&&L!==d?L:K;this.options.missingKeyHandler?this.options.missingKeyHandler(S,l,C,k,O,n):this.backendConnector&&this.backendConnector.saveMissing&&this.backendConnector.saveMissing(S,l,C,k,O,n),this.emit("missingKey",S,l,C,d)};this.options.saveMissing&&(this.options.saveMissingPlurals&&v?V.forEach((S=>{const C=this.pluralResolver.getSuffixes(S,n);I&&n[`defaultValue${this.options.pluralSeparator}zero`]&&C.indexOf(`${this.options.pluralSeparator}zero`)<0&&C.push(`${this.options.pluralSeparator}zero`),C.forEach((L=>{x([S],s+L,n[`defaultValue${L}`]||W)}))})):x(V,s,W))}d=this.extendTranslation(d,e,n,p,r),N&&d===s&&this.options.appendNamespaceToMissingKey&&(d=`${l}:${s}`),(N||_)&&this.options.parseMissingKeyHandler&&(d="v1"!==this.options.compatibilityAPI?this.options.parseMissingKeyHandler(this.options.appendNamespaceToMissingKey?`${l}:${s}`:s,_?d:void 0):this.options.parseMissingKeyHandler(d))}else{if(!n.returnObjects&&!this.options.returnObjects){this.options.returnedObjectHandler||this.logger.warn("accessing an object - but returnObjects options is not enabled!");const _=this.options.returnedObjectHandler?this.options.returnedObjectHandler(f,d,{...n,ns:i}):`key '${s} (${this.language})' returned an object instead of string.`;return o?(p.res=_,p.usedParams=this.getUsedParamsDetails(n),p):_}if(a){const _=Array.isArray(d),N=_?[]:{},v=_?b:f;for(const T in d)if(Object.prototype.hasOwnProperty.call(d,T)){const R=`${v}${a}${T}`;N[T]=this.translate(R,{...n,joinArrays:!1,ns:i}),N[T]===R&&(N[T]=d[T])}d=N}}return o?(p.res=d,p.usedParams=this.getUsedParamsDetails(n),p):d}extendTranslation(e,n,r,o,a){var s=this;if(this.i18nFormat&&this.i18nFormat.parse)e=this.i18nFormat.parse(e,{...this.options.interpolation.defaultVariables,...r},r.lng||this.language||o.usedLng,o.usedNS,o.usedKey,{resolved:o});else if(!r.skipInterpolation){r.interpolation&&this.interpolator.init({...r,interpolation:{...this.options.interpolation,...r.interpolation}});const u=Y(e)&&(r&&r.interpolation&&void 0!==r.interpolation.skipOnVariables?r.interpolation.skipOnVariables:this.options.interpolation.skipOnVariables);let c;if(u){const d=e.match(this.interpolator.nestingRegexp);c=d&&d.length}let p=r.replace&&!Y(r.replace)?r.replace:r;if(this.options.interpolation.defaultVariables&&(p={...this.options.interpolation.defaultVariables,...p}),e=this.interpolator.interpolate(e,p,r.lng||this.language||o.usedLng,r),u){const d=e.match(this.interpolator.nestingRegexp);c<(d&&d.length)&&(r.nest=!1)}!r.lng&&"v1"!==this.options.compatibilityAPI&&o&&o.res&&(r.lng=this.language||o.usedLng),!1!==r.nest&&(e=this.interpolator.nest(e,(function(){for(var d=arguments.length,f=new Array(d),b=0;b1&&void 0!==arguments[1]?arguments[1]:{};return Y(e)&&(e=[e]),e.forEach((l=>{if(this.isValidLookup(r))return;const u=this.extractFromKey(l,n),c=u.key;o=c;let p=u.namespaces;this.options.fallbackNS&&(p=p.concat(this.options.fallbackNS));const d=void 0!==n.count&&!Y(n.count),f=d&&!n.ordinal&&0===n.count&&this.pluralResolver.shouldUseIntlApi(),b=void 0!==n.context&&(Y(n.context)||"number"==typeof n.context)&&""!==n.context,A=n.lngs?n.lngs:this.languageUtils.toResolveHierarchy(n.lng||this.language,n.fallbackLng);p.forEach((y=>{this.isValidLookup(r)||(i=y,!Sg[`${A[0]}-${y}`]&&this.utils&&this.utils.hasLoadedNamespace&&!this.utils.hasLoadedNamespace(i)&&(Sg[`${A[0]}-${y}`]=!0,this.logger.warn(`key "${o}" for languages "${A.join(", ")}" won't get resolved as namespace "${i}" was not yet loaded`,"This means something IS WRONG in your setup. You access the t function before i18next.init / i18next.loadNamespace / i18next.changeLanguage was done. Wait for the callback or Promise to resolve before accessing it!!!")),A.forEach((h=>{if(this.isValidLookup(r))return;s=h;const g=[c];if(this.i18nFormat&&this.i18nFormat.addLookupKeys)this.i18nFormat.addLookupKeys(g,c,h,y,n);else{let _;d&&(_=this.pluralResolver.getSuffix(h,n.count,n));const N=`${this.options.pluralSeparator}zero`,v=`${this.options.pluralSeparator}ordinal${this.options.pluralSeparator}`;if(d&&(g.push(c+_),n.ordinal&&0===_.indexOf(v)&&g.push(c+_.replace(v,this.options.pluralSeparator)),f&&g.push(c+N)),b){const T=`${c}${this.options.contextSeparator}${n.context}`;g.push(T),d&&(g.push(T+_),n.ordinal&&0===_.indexOf(v)&&g.push(T+_.replace(v,this.options.pluralSeparator)),f&&g.push(T+N))}}let E;for(;E=g.pop();)this.isValidLookup(r)||(a=E,r=this.getResource(h,y,E,n))})))}))})),{res:r,usedKey:o,exactUsedKey:a,usedLng:s,usedNS:i}}isValidLookup(e){return!(void 0===e||!this.options.returnNull&&null===e||!this.options.returnEmptyString&&""===e)}getResource(e,n,r){let o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};return this.i18nFormat&&this.i18nFormat.getResource?this.i18nFormat.getResource(e,n,r,o):this.resourceStore.getResource(e,n,r,o)}getUsedParamsDetails(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const n=["defaultValue","ordinal","context","replace","lng","lngs","fallbackLng","ns","keySeparator","nsSeparator","returnObjects","returnDetails","joinArrays","postProcess","interpolation"],r=e.replace&&!Y(e.replace);let o=r?e.replace:e;if(r&&typeof e.count<"u"&&(o.count=e.count),this.options.interpolation.defaultVariables&&(o={...this.options.interpolation.defaultVariables,...o}),!r){o={...o};for(const a of n)delete o[a]}return o}static hasDefaultValue(e){const n="defaultValue";for(const r in e)if(Object.prototype.hasOwnProperty.call(e,r)&&n===r.substring(0,12)&&void 0!==e[r])return!0;return!1}}const _c=t=>t.charAt(0).toUpperCase()+t.slice(1);class Ng{constructor(e){this.options=e,this.supportedLngs=this.options.supportedLngs||!1,this.logger=Xt.create("languageUtils")}getScriptPartFromCode(e){if(!(e=ti(e))||e.indexOf("-")<0)return null;const n=e.split("-");return 2===n.length||(n.pop(),"x"===n[n.length-1].toLowerCase())?null:this.formatLanguageCode(n.join("-"))}getLanguagePartFromCode(e){if(!(e=ti(e))||e.indexOf("-")<0)return e;const n=e.split("-");return this.formatLanguageCode(n[0])}formatLanguageCode(e){if(Y(e)&&e.indexOf("-")>-1){if(typeof Intl<"u"&&typeof Intl.getCanonicalLocales<"u")try{let o=Intl.getCanonicalLocales(e)[0];if(o&&this.options.lowerCaseLng&&(o=o.toLowerCase()),o)return o}catch{}const n=["hans","hant","latn","cyrl","cans","mong","arab"];let r=e.split("-");return this.options.lowerCaseLng?r=r.map((o=>o.toLowerCase())):2===r.length?(r[0]=r[0].toLowerCase(),r[1]=r[1].toUpperCase(),n.indexOf(r[1].toLowerCase())>-1&&(r[1]=_c(r[1].toLowerCase()))):3===r.length&&(r[0]=r[0].toLowerCase(),2===r[1].length&&(r[1]=r[1].toUpperCase()),"sgn"!==r[0]&&2===r[2].length&&(r[2]=r[2].toUpperCase()),n.indexOf(r[1].toLowerCase())>-1&&(r[1]=_c(r[1].toLowerCase())),n.indexOf(r[2].toLowerCase())>-1&&(r[2]=_c(r[2].toLowerCase()))),r.join("-")}return this.options.cleanCode||this.options.lowerCaseLng?e.toLowerCase():e}isSupportedCode(e){return("languageOnly"===this.options.load||this.options.nonExplicitSupportedLngs)&&(e=this.getLanguagePartFromCode(e)),!this.supportedLngs||!this.supportedLngs.length||this.supportedLngs.indexOf(e)>-1}getBestMatchFromCodes(e){if(!e)return null;let n;return e.forEach((r=>{if(n)return;const o=this.formatLanguageCode(r);(!this.options.supportedLngs||this.isSupportedCode(o))&&(n=o)})),!n&&this.options.supportedLngs&&e.forEach((r=>{if(n)return;const o=this.getLanguagePartFromCode(r);if(this.isSupportedCode(o))return n=o;n=this.options.supportedLngs.find((a=>a===o?a:a.indexOf("-")<0&&o.indexOf("-")<0||!(a.indexOf("-")>0&&o.indexOf("-")<0&&a.substring(0,a.indexOf("-"))===o||0===a.indexOf(o)&&o.length>1)?void 0:a))})),n||(n=this.getFallbackCodes(this.options.fallbackLng)[0]),n}getFallbackCodes(e,n){if(!e)return[];if("function"==typeof e&&(e=e(n)),Y(e)&&(e=[e]),Array.isArray(e))return e;if(!n)return e.default||[];let r=e[n];return r||(r=e[this.getScriptPartFromCode(n)]),r||(r=e[this.formatLanguageCode(n)]),r||(r=e[this.getLanguagePartFromCode(n)]),r||(r=e.default),r||[]}toResolveHierarchy(e,n){const r=this.getFallbackCodes(n||this.options.fallbackLng||[],e),o=[],a=s=>{s&&(this.isSupportedCode(s)?o.push(s):this.logger.warn(`rejecting language code not found in supportedLngs: ${s}`))};return Y(e)&&(e.indexOf("-")>-1||e.indexOf("_")>-1)?("languageOnly"!==this.options.load&&a(this.formatLanguageCode(e)),"languageOnly"!==this.options.load&&"currentOnly"!==this.options.load&&a(this.getScriptPartFromCode(e)),"currentOnly"!==this.options.load&&a(this.getLanguagePartFromCode(e))):Y(e)&&a(this.formatLanguageCode(e)),r.forEach((s=>{o.indexOf(s)<0&&a(this.formatLanguageCode(s))})),o}}let eS=[{lngs:["ach","ak","am","arn","br","fil","gun","ln","mfe","mg","mi","oc","pt","pt-BR","tg","tl","ti","tr","uz","wa"],nr:[1,2],fc:1},{lngs:["af","an","ast","az","bg","bn","ca","da","de","dev","el","en","eo","es","et","eu","fi","fo","fur","fy","gl","gu","ha","hi","hu","hy","ia","it","kk","kn","ku","lb","mai","ml","mn","mr","nah","nap","nb","ne","nl","nn","no","nso","pa","pap","pms","ps","pt-PT","rm","sco","se","si","so","son","sq","sv","sw","ta","te","tk","ur","yo"],nr:[1,2],fc:2},{lngs:["ay","bo","cgg","fa","ht","id","ja","jbo","ka","km","ko","ky","lo","ms","sah","su","th","tt","ug","vi","wo","zh"],nr:[1],fc:3},{lngs:["be","bs","cnr","dz","hr","ru","sr","uk"],nr:[1,2,5],fc:4},{lngs:["ar"],nr:[0,1,2,3,11,100],fc:5},{lngs:["cs","sk"],nr:[1,2,5],fc:6},{lngs:["csb","pl"],nr:[1,2,5],fc:7},{lngs:["cy"],nr:[1,2,3,8],fc:8},{lngs:["fr"],nr:[1,2],fc:9},{lngs:["ga"],nr:[1,2,3,7,11],fc:10},{lngs:["gd"],nr:[1,2,3,20],fc:11},{lngs:["is"],nr:[1,2],fc:12},{lngs:["jv"],nr:[0,1],fc:13},{lngs:["kw"],nr:[1,2,3,4],fc:14},{lngs:["lt"],nr:[1,2,10],fc:15},{lngs:["lv"],nr:[1,2,0],fc:16},{lngs:["mk"],nr:[1,2],fc:17},{lngs:["mnk"],nr:[0,1,2],fc:18},{lngs:["mt"],nr:[1,2,11,20],fc:19},{lngs:["or"],nr:[2,1],fc:2},{lngs:["ro"],nr:[1,2,20],fc:20},{lngs:["sl"],nr:[5,1,2,3],fc:21},{lngs:["he","iw"],nr:[1,2,20,21],fc:22}],tS={1:t=>+(t>1),2:t=>+(1!=t),3:t=>0,4:t=>t%10==1&&t%100!=11?0:t%10>=2&&t%10<=4&&(t%100<10||t%100>=20)?1:2,5:t=>0==t?0:1==t?1:2==t?2:t%100>=3&&t%100<=10?3:t%100>=11?4:5,6:t=>1==t?0:t>=2&&t<=4?1:2,7:t=>1==t?0:t%10>=2&&t%10<=4&&(t%100<10||t%100>=20)?1:2,8:t=>1==t?0:2==t?1:8!=t&&11!=t?2:3,9:t=>+(t>=2),10:t=>1==t?0:2==t?1:t<7?2:t<11?3:4,11:t=>1==t||11==t?0:2==t||12==t?1:t>2&&t<20?2:3,12:t=>+(t%10!=1||t%100==11),13:t=>+(0!==t),14:t=>1==t?0:2==t?1:3==t?2:3,15:t=>t%10==1&&t%100!=11?0:t%10>=2&&(t%100<10||t%100>=20)?1:2,16:t=>t%10==1&&t%100!=11?0:0!==t?1:2,17:t=>1==t||t%10==1&&t%100!=11?0:1,18:t=>0==t?0:1==t?1:2,19:t=>1==t?0:0==t||t%100>1&&t%100<11?1:t%100>10&&t%100<20?2:3,20:t=>1==t?0:0==t||t%100>0&&t%100<20?1:2,21:t=>t%100==1?1:t%100==2?2:t%100==3||t%100==4?3:0,22:t=>1==t?0:2==t?1:(t<0||t>10)&&t%10==0?2:3};const nS=["v1","v2","v3"],rS=["v4"],Tg={zero:0,one:1,two:2,few:3,many:4,other:5};class aS{constructor(e){let n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};this.languageUtils=e,this.options=n,this.logger=Xt.create("pluralResolver"),(!this.options.compatibilityJSON||rS.includes(this.options.compatibilityJSON))&&(typeof Intl>"u"||!Intl.PluralRules)&&(this.options.compatibilityJSON="v3",this.logger.error("Your environment seems not to be Intl API compatible, use an Intl.PluralRules polyfill. Will fallback to the compatibilityJSON v3 format handling.")),this.rules=(()=>{const t={};return eS.forEach((e=>{e.lngs.forEach((n=>{t[n]={numbers:e.nr,plurals:tS[e.fc]}}))})),t})(),this.pluralRulesCache={}}addRule(e,n){this.rules[e]=n}clearCache(){this.pluralRulesCache={}}getRule(e){let n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(this.shouldUseIntlApi()){const r=ti("dev"===e?"en":e),o=n.ordinal?"ordinal":"cardinal",a=JSON.stringify({cleanedCode:r,type:o});if(a in this.pluralRulesCache)return this.pluralRulesCache[a];let s;try{s=new Intl.PluralRules(r,{type:o})}catch{if(!e.match(/-|_/))return;const l=this.languageUtils.getLanguagePartFromCode(e);s=this.getRule(l,n)}return this.pluralRulesCache[a]=s,s}return this.rules[e]||this.rules[this.languageUtils.getLanguagePartFromCode(e)]}needsPlural(e){let n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const r=this.getRule(e,n);return this.shouldUseIntlApi()?r&&r.resolvedOptions().pluralCategories.length>1:r&&r.numbers.length>1}getPluralFormsOfKey(e,n){let r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return this.getSuffixes(e,r).map((o=>`${n}${o}`))}getSuffixes(e){let n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const r=this.getRule(e,n);return r?this.shouldUseIntlApi()?r.resolvedOptions().pluralCategories.sort(((o,a)=>Tg[o]-Tg[a])).map((o=>`${this.options.prepend}${n.ordinal?`ordinal${this.options.prepend}`:""}${o}`)):r.numbers.map((o=>this.getSuffix(e,o,n))):[]}getSuffix(e,n){let r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const o=this.getRule(e,r);return o?this.shouldUseIntlApi()?`${this.options.prepend}${r.ordinal?`ordinal${this.options.prepend}`:""}${o.select(n)}`:this.getSuffixRetroCompatible(o,n):(this.logger.warn(`no plural rule found for: ${e}`),"")}getSuffixRetroCompatible(e,n){const r=e.noAbs?e.plurals(n):e.plurals(Math.abs(n));let o=e.numbers[r];this.options.simplifyPluralSuffix&&2===e.numbers.length&&1===e.numbers[0]&&(2===o?o="plural":1===o&&(o=""));const a=()=>this.options.prepend&&o.toString()?this.options.prepend+o.toString():o.toString();return"v1"===this.options.compatibilityJSON?1===o?"":"number"==typeof o?`_plural_${o.toString()}`:a():"v2"===this.options.compatibilityJSON||this.options.simplifyPluralSuffix&&2===e.numbers.length&&1===e.numbers[0]?a():this.options.prepend&&r.toString()?this.options.prepend+r.toString():r.toString()}shouldUseIntlApi(){return!nS.includes(this.options.compatibilityJSON)}}const wg=function(t,e,n){let r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:".",o=!(arguments.length>4&&void 0!==arguments[4])||arguments[4],a=((t,e,n)=>{const r=ei(t,n);return void 0!==r?r:ei(e,n)})(t,e,n);return!a&&o&&Y(n)&&(a=Ac(t,n,r),void 0===a&&(a=Ac(e,n,r))),a},vc=t=>t.replace(/\$/g,"$$$$");class sS{constructor(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.logger=Xt.create("interpolator"),this.options=e,this.format=e.interpolation&&e.interpolation.format||(n=>n),this.init(e)}init(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};e.interpolation||(e.interpolation={escapeValue:!0});const{escape:n,escapeValue:r,useRawValueToEscape:o,prefix:a,prefixEscaped:s,suffix:i,suffixEscaped:l,formatSeparator:u,unescapeSuffix:c,unescapePrefix:p,nestingPrefix:d,nestingPrefixEscaped:f,nestingSuffix:b,nestingSuffixEscaped:A,nestingOptionsSeparator:y,maxReplaces:h,alwaysFormat:g}=e.interpolation;this.escape=void 0!==n?n:WC,this.escapeValue=void 0===r||r,this.useRawValueToEscape=void 0!==o&&o,this.prefix=a?$r(a):s||"{{",this.suffix=i?$r(i):l||"}}",this.formatSeparator=u||",",this.unescapePrefix=c?"":p||"-",this.unescapeSuffix=this.unescapePrefix?"":c||"",this.nestingPrefix=d?$r(d):f||$r("$t("),this.nestingSuffix=b?$r(b):A||$r(")"),this.nestingOptionsSeparator=y||",",this.maxReplaces=h||1e3,this.alwaysFormat=void 0!==g&&g,this.resetRegExp()}reset(){this.options&&this.init(this.options)}resetRegExp(){const e=(n,r)=>n&&n.source===r?(n.lastIndex=0,n):new RegExp(r,"g");this.regexp=e(this.regexp,`${this.prefix}(.+?)${this.suffix}`),this.regexpUnescape=e(this.regexpUnescape,`${this.prefix}${this.unescapePrefix}(.+?)${this.unescapeSuffix}${this.suffix}`),this.nestingRegexp=e(this.nestingRegexp,`${this.nestingPrefix}(.+?)${this.nestingSuffix}`)}interpolate(e,n,r,o){let a,s,i;const l=this.options&&this.options.interpolation&&this.options.interpolation.defaultVariables||{},u=f=>{if(f.indexOf(this.formatSeparator)<0){const h=wg(n,l,f,this.options.keySeparator,this.options.ignoreJSONStructure);return this.alwaysFormat?this.format(h,void 0,r,{...o,...n,interpolationkey:f}):h}const b=f.split(this.formatSeparator),A=b.shift().trim(),y=b.join(this.formatSeparator).trim();return this.format(wg(n,l,A,this.options.keySeparator,this.options.ignoreJSONStructure),y,r,{...o,...n,interpolationkey:A})};this.resetRegExp();const c=o&&o.missingInterpolationHandler||this.options.missingInterpolationHandler,p=o&&o.interpolation&&void 0!==o.interpolation.skipOnVariables?o.interpolation.skipOnVariables:this.options.interpolation.skipOnVariables;return[{regex:this.regexpUnescape,safeValue:f=>vc(f)},{regex:this.regexp,safeValue:f=>this.escapeValue?vc(this.escape(f)):vc(f)}].forEach((f=>{for(i=0;a=f.regex.exec(e);){const b=a[1].trim();if(s=u(b),void 0===s)if("function"==typeof c){const y=c(e,a,o);s=Y(y)?y:""}else if(o&&Object.prototype.hasOwnProperty.call(o,b))s="";else{if(p){s=a[0];continue}this.logger.warn(`missed to pass in variable ${b} for interpolating ${e}`),s=""}else!Y(s)&&!this.useRawValueToEscape&&(s=bg(s));const A=f.safeValue(s);if(e=e.replace(a[0],A),p?(f.regex.lastIndex+=s.length,f.regex.lastIndex-=a[0].length):f.regex.lastIndex=0,i++,i>=this.maxReplaces)break}})),e}nest(e,n){let o,a,s,r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const i=(l,u)=>{const c=this.nestingOptionsSeparator;if(l.indexOf(c)<0)return l;const p=l.split(new RegExp(`${c}[ ]*{`));let d=`{${p[1]}`;l=p[0],d=this.interpolate(d,s);const f=d.match(/'/g),b=d.match(/"/g);(f&&f.length%2==0&&!b||b.length%2!=0)&&(d=d.replace(/'/g,'"'));try{s=JSON.parse(d),u&&(s={...u,...s})}catch(A){return this.logger.warn(`failed parsing options string in nesting for key ${l}`,A),`${l}${c}${d}`}return s.defaultValue&&s.defaultValue.indexOf(this.prefix)>-1&&delete s.defaultValue,l};for(;o=this.nestingRegexp.exec(e);){let l=[];s={...r},s=s.replace&&!Y(s.replace)?s.replace:s,s.applyPostProcessor=!1,delete s.defaultValue;let u=!1;if(-1!==o[0].indexOf(this.formatSeparator)&&!/{.*}/.test(o[1])){const c=o[1].split(this.formatSeparator).map((p=>p.trim()));o[1]=c.shift(),l=c,u=!0}if(a=n(i.call(this,o[1].trim(),s),s),a&&o[0]===e&&!Y(a))return a;Y(a)||(a=bg(a)),a||(this.logger.warn(`missed to resolve ${o[1]} for nesting ${e}`),a=""),u&&(a=l.reduce(((c,p)=>this.format(c,p,r.lng,{...r,interpolationkey:o[1].trim()})),a.trim())),e=e.replace(o[0],a),this.regexp.lastIndex=0}return e}}const zr=t=>{const e={};return(n,r,o)=>{let a=o;o&&o.interpolationkey&&o.formatParams&&o.formatParams[o.interpolationkey]&&o[o.interpolationkey]&&(a={...a,[o.interpolationkey]:void 0});const s=r+JSON.stringify(a);let i=e[s];return i||(i=t(ti(r),o),e[s]=i),i(n)}};class lS{constructor(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.logger=Xt.create("formatter"),this.options=e,this.formats={number:zr(((n,r)=>{const o=new Intl.NumberFormat(n,{...r});return a=>o.format(a)})),currency:zr(((n,r)=>{const o=new Intl.NumberFormat(n,{...r,style:"currency"});return a=>o.format(a)})),datetime:zr(((n,r)=>{const o=new Intl.DateTimeFormat(n,{...r});return a=>o.format(a)})),relativetime:zr(((n,r)=>{const o=new Intl.RelativeTimeFormat(n,{...r});return a=>o.format(a,r.range||"day")})),list:zr(((n,r)=>{const o=new Intl.ListFormat(n,{...r});return a=>o.format(a)}))},this.init(e)}init(e){let n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{interpolation:{}};this.formatSeparator=n.interpolation.formatSeparator||","}add(e,n){this.formats[e.toLowerCase().trim()]=n}addCached(e,n){this.formats[e.toLowerCase().trim()]=zr(n)}format(e,n,r){let o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};const a=n.split(this.formatSeparator);if(a.length>1&&a[0].indexOf("(")>1&&a[0].indexOf(")")<0&&a.find((i=>i.indexOf(")")>-1))){const i=a.findIndex((l=>l.indexOf(")")>-1));a[0]=[a[0],...a.splice(1,i)].join(this.formatSeparator)}return a.reduce(((i,l)=>{const{formatName:u,formatOptions:c}=(t=>{let e=t.toLowerCase().trim();const n={};if(t.indexOf("(")>-1){const r=t.split("(");e=r[0].toLowerCase().trim();const o=r[1].substring(0,r[1].length-1);"currency"===e&&o.indexOf(":")<0?n.currency||(n.currency=o.trim()):"relativetime"===e&&o.indexOf(":")<0?n.range||(n.range=o.trim()):o.split(";").forEach((s=>{if(s){const[i,...l]=s.split(":"),u=l.join(":").trim().replace(/^'+|'+$/g,""),c=i.trim();n[c]||(n[c]=u),"false"===u&&(n[c]=!1),"true"===u&&(n[c]=!0),isNaN(u)||(n[c]=parseInt(u,10))}}))}return{formatName:e,formatOptions:n}})(l);if(this.formats[u]){let p=i;try{const d=o&&o.formatParams&&o.formatParams[o.interpolationkey]||{},f=d.locale||d.lng||o.locale||o.lng||r;p=this.formats[u](i,f,{...c,...o,...d})}catch(d){this.logger.warn(d)}return p}return this.logger.warn(`there was no format function for ${u}`),i}),e)}}class cS extends ri{constructor(e,n,r){let o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};super(),this.backend=e,this.store=n,this.services=r,this.languageUtils=r.languageUtils,this.options=o,this.logger=Xt.create("backendConnector"),this.waitingReads=[],this.maxParallelReads=o.maxParallelReads||10,this.readingCalls=0,this.maxRetries=o.maxRetries>=0?o.maxRetries:5,this.retryTimeout=o.retryTimeout>=1?o.retryTimeout:350,this.state={},this.queue=[],this.backend&&this.backend.init&&this.backend.init(r,o.backend,o)}queueLoad(e,n,r,o){const a={},s={},i={},l={};return e.forEach((u=>{let c=!0;n.forEach((p=>{const d=`${u}|${p}`;!r.reload&&this.store.hasResourceBundle(u,p)?this.state[d]=2:this.state[d]<0||(1===this.state[d]?void 0===s[d]&&(s[d]=!0):(this.state[d]=1,c=!1,void 0===s[d]&&(s[d]=!0),void 0===a[d]&&(a[d]=!0),void 0===l[p]&&(l[p]=!0)))})),c||(i[u]=!0)})),(Object.keys(a).length||Object.keys(s).length)&&this.queue.push({pending:s,pendingCount:Object.keys(s).length,loaded:{},errors:[],callback:o}),{toLoad:Object.keys(a),pending:Object.keys(s),toLoadLanguages:Object.keys(i),toLoadNamespaces:Object.keys(l)}}loaded(e,n,r){const o=e.split("|"),a=o[0],s=o[1];n&&this.emit("failedLoading",a,s,n),!n&&r&&this.store.addResourceBundle(a,s,r,void 0,void 0,{skipCopy:!0}),this.state[e]=n?-1:2,n&&r&&(this.state[e]=0);const i={};this.queue.forEach((l=>{((t,e,n,r)=>{const{obj:o,k:a}=Xo(t,e,Object);o[a]=o[a]||[],o[a].push(n)})(l.loaded,[a],s),((t,e)=>{void 0!==t.pending[e]&&(delete t.pending[e],t.pendingCount--)})(l,e),n&&l.errors.push(n),0===l.pendingCount&&!l.done&&(Object.keys(l.loaded).forEach((u=>{i[u]||(i[u]={});const c=l.loaded[u];c.length&&c.forEach((p=>{void 0===i[u][p]&&(i[u][p]=!0)}))})),l.done=!0,l.errors.length?l.callback(l.errors):l.callback())})),this.emit("loaded",i),this.queue=this.queue.filter((l=>!l.done))}read(e,n,r){let o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:0,a=arguments.length>4&&void 0!==arguments[4]?arguments[4]:this.retryTimeout,s=arguments.length>5?arguments[5]:void 0;if(!e.length)return s(null,{});if(this.readingCalls>=this.maxParallelReads)return void this.waitingReads.push({lng:e,ns:n,fcName:r,tried:o,wait:a,callback:s});this.readingCalls++;const i=(u,c)=>{if(this.readingCalls--,this.waitingReads.length>0){const p=this.waitingReads.shift();this.read(p.lng,p.ns,p.fcName,p.tried,p.wait,p.callback)}u&&c&&o{this.read.call(this,e,n,r,o+1,2*a,s)}),a):s(u,c)},l=this.backend[r].bind(this.backend);if(2!==l.length)return l(e,n,i);try{const u=l(e,n);u&&"function"==typeof u.then?u.then((c=>i(null,c))).catch(i):i(null,u)}catch(u){i(u)}}prepareLoading(e,n){let r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},o=arguments.length>3?arguments[3]:void 0;if(!this.backend)return this.logger.warn("No backend was added via i18next.use. Will not load resources."),o&&o();Y(e)&&(e=this.languageUtils.toResolveHierarchy(e)),Y(n)&&(n=[n]);const a=this.queueLoad(e,n,r,o);if(!a.toLoad.length)return a.pending.length||o(),null;a.toLoad.forEach((s=>{this.loadOne(s)}))}load(e,n,r){this.prepareLoading(e,n,{},r)}reload(e,n,r){this.prepareLoading(e,n,{reload:!0},r)}loadOne(e){let n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";const r=e.split("|"),o=r[0],a=r[1];this.read(o,a,"read",void 0,void 0,((s,i)=>{s&&this.logger.warn(`${n}loading namespace ${a} for language ${o} failed`,s),!s&&i&&this.logger.log(`${n}loaded namespace ${a} for language ${o}`,i),this.loaded(e,s,i)}))}saveMissing(e,n,r,o,a){let s=arguments.length>5&&void 0!==arguments[5]?arguments[5]:{},i=arguments.length>6&&void 0!==arguments[6]?arguments[6]:()=>{};if(this.services.utils&&this.services.utils.hasLoadedNamespace&&!this.services.utils.hasLoadedNamespace(n))this.logger.warn(`did not save key "${r}" as the namespace "${n}" was not yet loaded`,"This means something IS WRONG in your setup. You access the t function before i18next.init / i18next.loadNamespace / i18next.changeLanguage was done. Wait for the callback or Promise to resolve before accessing it!!!");else if(null!=r&&""!==r){if(this.backend&&this.backend.create){const l={...s,isUpdate:a},u=this.backend.create.bind(this.backend);if(u.length<6)try{let c;c=5===u.length?u(e,n,r,o,l):u(e,n,r,o),c&&"function"==typeof c.then?c.then((p=>i(null,p))).catch(i):i(null,c)}catch(c){i(c)}else u(e,n,r,o,i,l)}!e||!e[0]||this.store.addResource(e[0],n,r,o)}}}const xg=()=>({debug:!1,initImmediate:!0,ns:["translation"],defaultNS:["translation"],fallbackLng:["dev"],fallbackNS:!1,supportedLngs:!1,nonExplicitSupportedLngs:!1,load:"all",preload:!1,simplifyPluralSuffix:!0,keySeparator:".",nsSeparator:":",pluralSeparator:"_",contextSeparator:"_",partialBundledLanguages:!1,saveMissing:!1,updateMissing:!1,saveMissingTo:"fallback",saveMissingPlurals:!0,missingKeyHandler:!1,missingInterpolationHandler:!1,postProcess:!1,postProcessPassResolved:!1,returnNull:!1,returnEmptyString:!0,returnObjects:!1,joinArrays:!1,returnedObjectHandler:!1,parseMissingKeyHandler:!1,appendNamespaceToMissingKey:!1,appendNamespaceToCIMode:!1,overloadTranslationOptionHandler:t=>{let e={};if("object"==typeof t[1]&&(e=t[1]),Y(t[1])&&(e.defaultValue=t[1]),Y(t[2])&&(e.tDescription=t[2]),"object"==typeof t[2]||"object"==typeof t[3]){const n=t[3]||t[2];Object.keys(n).forEach((r=>{e[r]=n[r]}))}return e},interpolation:{escapeValue:!0,format:t=>t,prefix:"{{",suffix:"}}",formatSeparator:",",unescapePrefix:"-",nestingPrefix:"$t(",nestingSuffix:")",nestingOptionsSeparator:",",maxReplaces:1e3,skipOnVariables:!0}}),Rg=t=>(Y(t.ns)&&(t.ns=[t.ns]),Y(t.fallbackLng)&&(t.fallbackLng=[t.fallbackLng]),Y(t.fallbackNS)&&(t.fallbackNS=[t.fallbackNS]),t.supportedLngs&&t.supportedLngs.indexOf("cimode")<0&&(t.supportedLngs=t.supportedLngs.concat(["cimode"])),t),ai=()=>{};class Qo extends ri{constructor(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=arguments.length>1?arguments[1]:void 0;if(super(),this.options=Rg(e),this.services={},this.logger=Xt,this.modules={external:[]},(t=>{Object.getOwnPropertyNames(Object.getPrototypeOf(t)).forEach((n=>{"function"==typeof t[n]&&(t[n]=t[n].bind(t))}))})(this),n&&!this.isInitialized&&!e.isClone){if(!this.options.initImmediate)return this.init(e,n),this;setTimeout((()=>{this.init(e,n)}),0)}}init(){var e=this;let n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},r=arguments.length>1?arguments[1]:void 0;this.isInitializing=!0,"function"==typeof n&&(r=n,n={}),!n.defaultNS&&!1!==n.defaultNS&&n.ns&&(Y(n.ns)?n.defaultNS=n.ns:n.ns.indexOf("translation")<0&&(n.defaultNS=n.ns[0]));const o=xg();this.options={...o,...this.options,...Rg(n)},"v1"!==this.options.compatibilityAPI&&(this.options.interpolation={...o.interpolation,...this.options.interpolation}),void 0!==n.keySeparator&&(this.options.userDefinedKeySeparator=n.keySeparator),void 0!==n.nsSeparator&&(this.options.userDefinedNsSeparator=n.nsSeparator);const a=c=>c?"function"==typeof c?new c:c:null;if(!this.options.isClone){let c;this.modules.logger?Xt.init(a(this.modules.logger),this.options):Xt.init(null,this.options),this.modules.formatter?c=this.modules.formatter:typeof Intl<"u"&&(c=lS);const p=new Ng(this.options);this.store=new Dg(this.options.resources,this.options);const d=this.services;d.logger=Xt,d.resourceStore=this.store,d.languageUtils=p,d.pluralResolver=new aS(p,{prepend:this.options.pluralSeparator,compatibilityJSON:this.options.compatibilityJSON,simplifyPluralSuffix:this.options.simplifyPluralSuffix}),c&&(!this.options.interpolation.format||this.options.interpolation.format===o.interpolation.format)&&(d.formatter=a(c),d.formatter.init(d,this.options),this.options.interpolation.format=d.formatter.format.bind(d.formatter)),d.interpolator=new sS(this.options),d.utils={hasLoadedNamespace:this.hasLoadedNamespace.bind(this)},d.backendConnector=new cS(a(this.modules.backend),d.resourceStore,d,this.options),d.backendConnector.on("*",(function(f){for(var b=arguments.length,A=new Array(b>1?b-1:0),y=1;y1?b-1:0),y=1;y{f.init&&f.init(this)}))}if(this.format=this.options.interpolation.format,r||(r=ai),this.options.fallbackLng&&!this.services.languageDetector&&!this.options.lng){const c=this.services.languageUtils.getFallbackCodes(this.options.fallbackLng);c.length>0&&"dev"!==c[0]&&(this.options.lng=c[0])}!this.services.languageDetector&&!this.options.lng&&this.logger.warn("init: no languageDetector is used and no lng is defined"),["getResource","hasResourceBundle","getResourceBundle","getDataByLanguage"].forEach((c=>{this[c]=function(){return e.store[c](...arguments)}})),["addResource","addResources","addResourceBundle","removeResourceBundle"].forEach((c=>{this[c]=function(){return e.store[c](...arguments),e}}));const l=Yo(),u=()=>{const c=(p,d)=>{this.isInitializing=!1,this.isInitialized&&!this.initializedStoreOnce&&this.logger.warn("init: i18next is already initialized. You should call init just once!"),this.isInitialized=!0,this.options.isClone||this.logger.log("initialized",this.options),this.emit("initialized",this.options),l.resolve(d),r(p,d)};if(this.languages&&"v1"!==this.options.compatibilityAPI&&!this.isInitialized)return c(null,this.t.bind(this));this.changeLanguage(this.options.lng,c)};return this.options.resources||!this.options.initImmediate?u():setTimeout(u,0),l}loadResources(e){let r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:ai;const o=Y(e)?e:this.language;if("function"==typeof e&&(r=e),!this.options.resources||this.options.partialBundledLanguages){if(o&&"cimode"===o.toLowerCase()&&(!this.options.preload||0===this.options.preload.length))return r();const a=[],s=i=>{i&&"cimode"!==i&&this.services.languageUtils.toResolveHierarchy(i).forEach((u=>{"cimode"!==u&&a.indexOf(u)<0&&a.push(u)}))};o?s(o):this.services.languageUtils.getFallbackCodes(this.options.fallbackLng).forEach((l=>s(l))),this.options.preload&&this.options.preload.forEach((i=>s(i))),this.services.backendConnector.load(a,this.options.ns,(i=>{!i&&!this.resolvedLanguage&&this.language&&this.setResolvedLanguage(this.language),r(i)}))}else r(null)}reloadResources(e,n,r){const o=Yo();return"function"==typeof e&&(r=e,e=void 0),"function"==typeof n&&(r=n,n=void 0),e||(e=this.languages),n||(n=this.options.ns),r||(r=ai),this.services.backendConnector.reload(e,n,(a=>{o.resolve(),r(a)})),o}use(e){if(!e)throw new Error("You are passing an undefined module! Please check the object you are passing to i18next.use()");if(!e.type)throw new Error("You are passing a wrong module! Please check the object you are passing to i18next.use()");return"backend"===e.type&&(this.modules.backend=e),("logger"===e.type||e.log&&e.warn&&e.error)&&(this.modules.logger=e),"languageDetector"===e.type&&(this.modules.languageDetector=e),"i18nFormat"===e.type&&(this.modules.i18nFormat=e),"postProcessor"===e.type&&Cg.addPostProcessor(e),"formatter"===e.type&&(this.modules.formatter=e),"3rdParty"===e.type&&this.modules.external.push(e),this}setResolvedLanguage(e){if(e&&this.languages&&!(["cimode","dev"].indexOf(e)>-1))for(let n=0;n-1)&&this.store.hasLanguageSomeTranslations(r)){this.resolvedLanguage=r;break}}}changeLanguage(e,n){var r=this;this.isLanguageChangingTo=e;const o=Yo();this.emit("languageChanging",e);const a=l=>{this.language=l,this.languages=this.services.languageUtils.toResolveHierarchy(l),this.resolvedLanguage=void 0,this.setResolvedLanguage(l)},s=(l,u)=>{u?(a(u),this.translator.changeLanguage(u),this.isLanguageChangingTo=void 0,this.emit("languageChanged",u),this.logger.log("languageChanged",u)):this.isLanguageChangingTo=void 0,o.resolve((function(){return r.t(...arguments)})),n&&n(l,(function(){return r.t(...arguments)}))},i=l=>{!e&&!l&&this.services.languageDetector&&(l=[]);const u=Y(l)?l:this.services.languageUtils.getBestMatchFromCodes(l);u&&(this.language||a(u),this.translator.language||this.translator.changeLanguage(u),this.services.languageDetector&&this.services.languageDetector.cacheUserLanguage&&this.services.languageDetector.cacheUserLanguage(u)),this.loadResources(u,(c=>{s(c,u)}))};return e||!this.services.languageDetector||this.services.languageDetector.async?!e&&this.services.languageDetector&&this.services.languageDetector.async?0===this.services.languageDetector.detect.length?this.services.languageDetector.detect().then(i):this.services.languageDetector.detect(i):i(e):i(this.services.languageDetector.detect()),o}getFixedT(e,n,r){var o=this;const a=function(s,i){let l;if("object"!=typeof i){for(var u=arguments.length,c=new Array(u>2?u-2:0),p=2;p`${l.keyPrefix}${d}${b}`)):l.keyPrefix?`${l.keyPrefix}${d}${s}`:s,o.t(f,l)};return Y(e)?a.lng=e:a.lngs=e,a.ns=n,a.keyPrefix=r,a}t(){return this.translator&&this.translator.translate(...arguments)}exists(){return this.translator&&this.translator.exists(...arguments)}setDefaultNamespace(e){this.options.defaultNS=e}hasLoadedNamespace(e){let n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(!this.isInitialized)return this.logger.warn("hasLoadedNamespace: i18next was not initialized",this.languages),!1;if(!this.languages||!this.languages.length)return this.logger.warn("hasLoadedNamespace: i18n.languages were undefined or empty",this.languages),!1;const r=n.lng||this.resolvedLanguage||this.languages[0],o=!!this.options&&this.options.fallbackLng,a=this.languages[this.languages.length-1];if("cimode"===r.toLowerCase())return!0;const s=(i,l)=>{const u=this.services.backendConnector.state[`${i}|${l}`];return-1===u||0===u||2===u};if(n.precheck){const i=n.precheck(this,s);if(void 0!==i)return i}return!!(this.hasResourceBundle(r,e)||!this.services.backendConnector.backend||this.options.resources&&!this.options.partialBundledLanguages||s(r,e)&&(!o||s(a,e)))}loadNamespaces(e,n){const r=Yo();return this.options.ns?(Y(e)&&(e=[e]),e.forEach((o=>{this.options.ns.indexOf(o)<0&&this.options.ns.push(o)})),this.loadResources((o=>{r.resolve(),n&&n(o)})),r):(n&&n(),Promise.resolve())}loadLanguages(e,n){const r=Yo();Y(e)&&(e=[e]);const o=this.options.preload||[],a=e.filter((s=>o.indexOf(s)<0&&this.services.languageUtils.isSupportedCode(s)));return a.length?(this.options.preload=o.concat(a),this.loadResources((s=>{r.resolve(),n&&n(s)})),r):(n&&n(),Promise.resolve())}dir(e){if(e||(e=this.resolvedLanguage||(this.languages&&this.languages.length>0?this.languages[0]:this.language)),!e)return"rtl";const r=this.services&&this.services.languageUtils||new Ng(xg());return["ar","shu","sqr","ssh","xaa","yhd","yud","aao","abh","abv","acm","acq","acw","acx","acy","adf","ads","aeb","aec","afb","ajp","apc","apd","arb","arq","ars","ary","arz","auz","avl","ayh","ayl","ayn","ayp","bbz","pga","he","iw","ps","pbt","pbu","pst","prp","prd","ug","ur","ydd","yds","yih","ji","yi","hbo","men","xmn","fa","jpr","peo","pes","prs","dv","sam","ckb"].indexOf(r.getLanguagePartFromCode(e))>-1||e.toLowerCase().indexOf("-arab")>1?"rtl":"ltr"}static createInstance(){return new Qo(arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},arguments.length>1?arguments[1]:void 0)}cloneInstance(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:ai;const r=e.forkResourceStore;r&&delete e.forkResourceStore;const o={...this.options,...e,isClone:!0},a=new Qo(o);return(void 0!==e.debug||void 0!==e.prefix)&&(a.logger=a.logger.clone(e)),["store","services","language"].forEach((i=>{a[i]=this[i]})),a.services={...this.services},a.services.utils={hasLoadedNamespace:a.hasLoadedNamespace.bind(a)},r&&(a.store=new Dg(this.store.data,o),a.services.resourceStore=a.store),a.translator=new oi(a.services,o),a.translator.on("*",(function(i){for(var l=arguments.length,u=new Array(l>1?l-1:0),c=1;c4&&void 0!==arguments[4]?arguments[4]:{path:"/",sameSite:"strict"};r&&(a.expires=new Date,a.expires.setTime(a.expires.getTime()+60*r*1e3)),o&&(a.domain=o),document.cookie=function(e,n,r){var o=r||{};o.path=o.path||"/";var a=encodeURIComponent(n),s="".concat(e,"=").concat(a);if(o.maxAge>0){var i=o.maxAge-0;if(Number.isNaN(i))throw new Error("maxAge should be a Number");s+="; Max-Age=".concat(Math.floor(i))}if(o.domain){if(!kg.test(o.domain))throw new TypeError("option domain is invalid");s+="; Domain=".concat(o.domain)}if(o.path){if(!kg.test(o.path))throw new TypeError("option path is invalid");s+="; Path=".concat(o.path)}if(o.expires){if("function"!=typeof o.expires.toUTCString)throw new TypeError("option expires is invalid");s+="; Expires=".concat(o.expires.toUTCString())}if(o.httpOnly&&(s+="; HttpOnly"),o.secure&&(s+="; Secure"),o.sameSite)switch("string"==typeof o.sameSite?o.sameSite.toLowerCase():o.sameSite){case!0:s+="; SameSite=Strict";break;case"lax":s+="; SameSite=Lax";break;case"strict":s+="; SameSite=Strict";break;case"none":s+="; SameSite=None";break;default:throw new TypeError("option sameSite is invalid")}return s}(e,encodeURIComponent(n),a)},Ig_read=function(e){for(var n="".concat(e,"="),r=document.cookie.split(";"),o=0;o-1&&(r=window.location.hash.substring(window.location.hash.indexOf("?")));for(var a=r.substring(1).split("&"),s=0;s0)a[s].substring(0,i)===e.lookupQuerystring&&(n=a[s].substring(i+1))}}return n}},ea=null,Mg=function(){if(null!==ea)return ea;try{ea="undefined"!==window&&null!==window.localStorage;var e="i18next.translate.boo";window.localStorage.setItem(e,"foo"),window.localStorage.removeItem(e)}catch{ea=!1}return ea},yS={name:"localStorage",lookup:function(e){var n;if(e.lookupLocalStorage&&Mg()){var r=window.localStorage.getItem(e.lookupLocalStorage);r&&(n=r)}return n},cacheUserLanguage:function(e,n){n.lookupLocalStorage&&Mg()&&window.localStorage.setItem(n.lookupLocalStorage,e)}},ta=null,Fg=function(){if(null!==ta)return ta;try{ta="undefined"!==window&&null!==window.sessionStorage;var e="i18next.translate.boo";window.sessionStorage.setItem(e,"foo"),window.sessionStorage.removeItem(e)}catch{ta=!1}return ta},DS={name:"sessionStorage",lookup:function(e){var n;if(e.lookupSessionStorage&&Fg()){var r=window.sessionStorage.getItem(e.lookupSessionStorage);r&&(n=r)}return n},cacheUserLanguage:function(e,n){n.lookupSessionStorage&&Fg()&&window.sessionStorage.setItem(n.lookupSessionStorage,e)}},CS={name:"navigator",lookup:function(e){var n=[];if(typeof navigator<"u"){if(navigator.languages)for(var r=0;r0?n:void 0}},SS={name:"htmlTag",lookup:function(e){var n,r=e.htmlTag||(typeof document<"u"?document.documentElement:null);return r&&"function"==typeof r.getAttribute&&(n=r.getAttribute("lang")),n}},NS={name:"path",lookup:function(e){var n;if(typeof window<"u"){var r=window.location.pathname.match(/\/([a-zA-Z-]*)/g);if(r instanceof Array)if("number"==typeof e.lookupFromPathIndex){if("string"!=typeof r[e.lookupFromPathIndex])return;n=r[e.lookupFromPathIndex].replace("/","")}else n=r[0].replace("/","")}return n}},TS={name:"subdomain",lookup:function(e){var n="number"==typeof e.lookupFromSubdomainIndex?e.lookupFromSubdomainIndex+1:1,r=typeof window<"u"&&window.location&&window.location.hostname&&window.location.hostname.match(/^(\w{2,5})\.(([a-z0-9-]{1,63}\.[a-z]{2,6})|localhost)/i);if(r)return r[n]}},Bg=!1;try{document.cookie,Bg=!0}catch{}var Pg=["querystring","cookie","localStorage","sessionStorage","navigator","htmlTag"];Bg||Pg.splice(1,1);var Ug=function(t,e,n){return e&&Lg(t.prototype,e),n&&Lg(t,n),Object.defineProperty(t,"prototype",{writable:!1}),t}((function t(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};(function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")})(this,t),this.type="languageDetector",this.detectors={},this.init(e,n)}),[{key:"init",value:function(n){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};this.services=n||{languageUtils:{}},this.options=function(t){return hS.call(ES.call(arguments,1),(function(e){if(e)for(var n in e)void 0===t[n]&&(t[n]=e[n])})),t}(r,this.options||{},{order:Pg,lookupQuerystring:"lng",lookupCookie:"i18next",lookupLocalStorage:"i18nextLng",lookupSessionStorage:"i18nextLng",caches:["localStorage"],excludeCacheFor:["cimode"],convertDetectedLanguage:function(e){return e}}),"string"==typeof this.options.convertDetectedLanguage&&this.options.convertDetectedLanguage.indexOf("15897")>-1&&(this.options.convertDetectedLanguage=function(a){return a.replace("-","_")}),this.options.lookupFromUrlIndex&&(this.options.lookupFromPathIndex=this.options.lookupFromUrlIndex),this.i18nOptions=o,this.addDetector(_S),this.addDetector(vS),this.addDetector(yS),this.addDetector(DS),this.addDetector(CS),this.addDetector(SS),this.addDetector(NS),this.addDetector(TS)}},{key:"addDetector",value:function(n){return this.detectors[n.name]=n,this}},{key:"detect",value:function(n){var r=this;n||(n=this.options.order);var o=[];return n.forEach((function(a){if(r.detectors[a]){var s=r.detectors[a].lookup(r.options);s&&"string"==typeof s&&(s=[s]),s&&(o=o.concat(s))}})),o=o.map((function(a){return r.options.convertDetectedLanguage(a)})),this.services.languageUtils.getBestMatchFromCodes?o:o.length>0?o[0]:null}},{key:"cacheUserLanguage",value:function(n,r){var o=this;r||(r=this.options.caches),r&&(this.options.excludeCacheFor&&this.options.excludeCacheFor.indexOf(n)>-1||r.forEach((function(a){o.detectors[a]&&o.detectors[a].cacheUserLanguage(n,o.options)})))}}]);Ug.type="languageDetector";const WS={en:{common:{chat:{"send-message":"Send a message","reset-chat":"Reset Chat"}}},zh:{common:{chat:{"send-message":null,"reset-chat":null}}},"zh-tw":{common:{chat:{"send-message":null,"reset-chat":null}}},es:{common:{chat:{"send-message":null,"reset-chat":null}}},de:{common:{chat:{"send-message":null,"reset-chat":null}}},fr:{common:{chat:{"send-message":"Envoyer un message","reset-chat":"Réinitialiser la conversation"}}},ko:{common:{chat:{"send-message":null,"reset-chat":null}}},ru:{common:{chat:{"send-message":null,"reset-chat":null}}},it:{common:{chat:{"send-message":null,"reset-chat":null}}},pt:{common:{chat:{"send-message":null,"reset-chat":null}}},he:{common:{chat:{"send-message":null,"reset-chat":null}}},nl:{common:{chat:{"send-message":null,"reset-chat":null}}},vi:{common:{chat:{"send-message":null,"reset-chat":null}}},fa:{common:{chat:{"send-message":null,"reset-chat":null}}},tr:{common:{chat:{"send-message":null,"reset-chat":null}}},ar:{common:{chat:{"send-message":null,"reset-chat":null}}},da:{common:{chat:{"send-message":null,"reset-chat":null}}},ja:{common:{chat:{"send-message":null,"reset-chat":null}}}};const qg=document.createElement("div");document.body.appendChild(qg);const In=Object.assign({},(null==(Hg=null==document?void 0:document.currentScript)?void 0:Hg.dataset)||{}),ae={settings:In,stylesSrc:function(t=null){try{const e=new URL(t);return e.pathname=e.pathname.replace("anythingllm-chat-widget.js","anythingllm-chat-widget.min.css").replace("anythingllm-chat-widget.min.js","anythingllm-chat-widget.min.css"),e.toString()}catch{return""}}(null==(Vg=null==document?void 0:document.currentScript)?void 0:Vg.src),USER_STYLES:{msgBg:(null==In?void 0:In.userBgColor)??"#3DBEF5",base:"allm-text-white allm-rounded-t-[18px] allm-rounded-bl-[18px] allm-rounded-br-[4px] allm-mx-[20px]"},ASSISTANT_STYLES:{msgBg:(null==In?void 0:In.assistantBgColor)??"#FFFFFF",base:"allm-text-[#222628] allm-rounded-t-[18px] allm-rounded-br-[18px] allm-rounded-bl-[4px] allm-mr-[37px] allm-ml-[9px]"}};(function(t){const e=(null==t?void 0:t.language)||"en";Fe.use(LC).use(Ug).init({fallbackLng:"en",lng:e,debug:!1,defaultNS:"common",resources:WS,load:"languageOnly",lowerCaseLng:!0,detection:{order:["localStorage","navigator"],lookupLocalStorage:"allm_embed_language"},interpolation:{escapeValue:!1}})})(In),pi.createRoot(qg).render(w.jsx(m.StrictMode,{children:w.jsx((function(){const{isChatOpen:t,toggleOpenChat:e}=function(){var r;const[t,e]=U.useState(!(null==(r=null==window?void 0:window.localStorage)||!r.getItem(_u))||!1);return{isChatOpen:t,toggleOpenChat:function(o){!0===o&&window.localStorage.setItem(_u,"1"),!1===o&&window.localStorage.removeItem(_u),e(o)}}}(),n=function(){const[t,e]=U.useState({loaded:!1,...Z0});return U.useEffect((()=>{!function(){if(!document)return!1;if(!ae.settings.baseApiUrl||!ae.settings.embedId)throw new Error("[AnythingLLM Embed Module::Abort] - Invalid script tag setup detected. Missing required parameters for boot!");e({...Z0,...LE(ae.settings),loaded:!0})}()}),[document]),t}(),r=K0();if(U.useEffect((()=>{"on"===n.openOnLoad&&e(!0)}),[n.loaded]),!n.loaded)return null;const o={"bottom-left":"allm-bottom-0 allm-left-0 allm-ml-4","bottom-right":"allm-bottom-0 allm-right-0 allm-mr-4","top-left":"allm-top-0 allm-left-0 allm-ml-4 allm-mt-4","top-right":"allm-top-0 allm-right-0 allm-mr-4 allm-mt-4"},a=n.position||"bottom-right",s=n.windowWidth??"400px",i=n.windowHeight??"700px";return w.jsxs(MC,{i18n:Fe,children:[w.jsx(UE,{}),w.jsx("div",{id:"anything-llm-embed-chat-container",className:"allm-fixed allm-inset-0 allm-z-50 "+(t?"allm-block":"allm-hidden"),children:w.jsx("div",{style:{maxWidth:s,maxHeight:i,height:"100%"},className:`allm-h-full allm-w-full allm-bg-white allm-fixed allm-bottom-0 allm-right-0 allm-mb-4 allm-md:mr-4 allm-rounded-2xl allm-border allm-border-gray-300 allm-shadow-[0_4px_14px_rgba(0,0,0,0.25)] allm-flex allm-flex-col ${o[a]}`,id:"anything-llm-chat",children:t&&w.jsx(qC,{closeChat:()=>e(!1),settings:n,sessionId:r})})}),!t&&w.jsx("div",{id:"anything-llm-embed-chat-button-container",className:`allm-fixed allm-bottom-0 ${o[a]} allm-mb-4 allm-z-50`,children:w.jsx(h_,{settings:n,isOpen:t,toggleOpen:()=>e(!0)})})]})}),{})})),_t.embedderSettings=ae,Object.defineProperty(_t,Symbol.toStringTag,{value:"Module"})})); \ No newline at end of file diff --git a/frontend/public/favicon.ico b/frontend/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..920576413e41f0df33ae10ab69238cb4321eb1c2 Binary files /dev/null and b/frontend/public/favicon.ico differ diff --git a/frontend/public/favicon.png b/frontend/public/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..e603a3d8932204abe1679120e0fde1fb625e0bf1 --- /dev/null +++ b/frontend/public/favicon.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:538d36ef4217492336c50fb0dd0f6c1fe0c9010cc7c20991b4bda27ce3809fc4 +size 3624 diff --git a/frontend/public/fonts/PlusJakartaSans.ttf b/frontend/public/fonts/PlusJakartaSans.ttf new file mode 100644 index 0000000000000000000000000000000000000000..8148f97509de5c5ba1d6629cbdbffad2f2b7d705 --- /dev/null +++ b/frontend/public/fonts/PlusJakartaSans.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e493fee2b67aed27c39f8eea876209ffc702dd4758b8fac868ffaea600abb576 +size 176144 diff --git a/frontend/public/robots.txt b/frontend/public/robots.txt new file mode 100644 index 0000000000000000000000000000000000000000..77470cb39f05f70a5b709b68304d0756bab75a0d --- /dev/null +++ b/frontend/public/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow: / \ No newline at end of file diff --git a/frontend/scripts/postbuild.js b/frontend/scripts/postbuild.js new file mode 100644 index 0000000000000000000000000000000000000000..bcba17bae273a3a36beb87fe5f402b850be2db40 --- /dev/null +++ b/frontend/scripts/postbuild.js @@ -0,0 +1,8 @@ +import { renameSync } from 'fs'; +import { fileURLToPath } from 'url'; +import path from 'path'; +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +console.log(`Running frontend post build script...`) +renameSync(path.resolve(__dirname, '../dist/index.html'), path.resolve(__dirname, '../dist/_index.html')); +console.log(`index.html renamed to _index.html so SSR of the index page can be assumed.`); \ No newline at end of file diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx new file mode 100644 index 0000000000000000000000000000000000000000..a2bed2ecca53c9c10f8cdd1ff1ceed9678d7c281 --- /dev/null +++ b/frontend/src/App.jsx @@ -0,0 +1,285 @@ +import React, { lazy, Suspense } from "react"; +import { Routes, Route } from "react-router-dom"; +import { I18nextProvider } from "react-i18next"; +import { ContextWrapper } from "@/AuthContext"; +import PrivateRoute, { + AdminRoute, + ManagerRoute, +} from "@/components/PrivateRoute"; +import { ToastContainer } from "react-toastify"; +import "react-toastify/dist/ReactToastify.css"; +import Login from "@/pages/Login"; +import SimpleSSOPassthrough from "@/pages/Login/SSO/simple"; +import OnboardingFlow from "@/pages/OnboardingFlow"; +import i18n from "./i18n"; + +import { PfpProvider } from "./PfpContext"; +import { LogoProvider } from "./LogoContext"; +import { FullScreenLoader } from "./components/Preloader"; +import { ThemeProvider } from "./ThemeContext"; +import KeyboardShortcutsHelp from "@/components/KeyboardShortcutsHelp"; + +const Main = lazy(() => import("@/pages/Main")); +const InvitePage = lazy(() => import("@/pages/Invite")); +const WorkspaceChat = lazy(() => import("@/pages/WorkspaceChat")); +const AdminUsers = lazy(() => import("@/pages/Admin/Users")); +const AdminInvites = lazy(() => import("@/pages/Admin/Invitations")); +const AdminWorkspaces = lazy(() => import("@/pages/Admin/Workspaces")); +const AdminLogs = lazy(() => import("@/pages/Admin/Logging")); +const AdminAgents = lazy(() => import("@/pages/Admin/Agents")); +const GeneralChats = lazy(() => import("@/pages/GeneralSettings/Chats")); +const InterfaceSettings = lazy( + () => import("@/pages/GeneralSettings/Settings/Interface") +); +const BrandingSettings = lazy( + () => import("@/pages/GeneralSettings/Settings/Branding") +); + +const ChatSettings = lazy( + () => import("@/pages/GeneralSettings/Settings/Chat") +); + +const GeneralApiKeys = lazy(() => import("@/pages/GeneralSettings/ApiKeys")); +const GeneralLLMPreference = lazy( + () => import("@/pages/GeneralSettings/LLMPreference") +); +const GeneralTranscriptionPreference = lazy( + () => import("@/pages/GeneralSettings/TranscriptionPreference") +); +const GeneralAudioPreference = lazy( + () => import("@/pages/GeneralSettings/AudioPreference") +); +const GeneralEmbeddingPreference = lazy( + () => import("@/pages/GeneralSettings/EmbeddingPreference") +); +const EmbeddingTextSplitterPreference = lazy( + () => import("@/pages/GeneralSettings/EmbeddingTextSplitterPreference") +); +const GeneralVectorDatabase = lazy( + () => import("@/pages/GeneralSettings/VectorDatabase") +); +const GeneralSecurity = lazy(() => import("@/pages/GeneralSettings/Security")); +const GeneralBrowserExtension = lazy( + () => import("@/pages/GeneralSettings/BrowserExtensionApiKey") +); +const WorkspaceSettings = lazy(() => import("@/pages/WorkspaceSettings")); + +const ChatEmbedWidgets = lazy( + () => import("@/pages/GeneralSettings/ChatEmbedWidgets") +); +const PrivacyAndData = lazy( + () => import("@/pages/GeneralSettings/PrivacyAndData") +); +const ExperimentalFeatures = lazy( + () => import("@/pages/Admin/ExperimentalFeatures") +); +const LiveDocumentSyncManage = lazy( + () => import("@/pages/Admin/ExperimentalFeatures/Features/LiveSync/manage") +); +const AgentBuilder = lazy(() => import("@/pages/Admin/AgentBuilder")); +const CommunityHubTrending = lazy( + () => import("@/pages/GeneralSettings/CommunityHub/Trending") +); +const CommunityHubAuthentication = lazy( + () => import("@/pages/GeneralSettings/CommunityHub/Authentication") +); +const CommunityHubImportItem = lazy( + () => import("@/pages/GeneralSettings/CommunityHub/ImportItem") +); +const SystemPromptVariables = lazy( + () => import("@/pages/Admin/SystemPromptVariables") +); +const MobileConnections = lazy( + () => import("@/pages/GeneralSettings/MobileConnections") +); + +export default function App() { + return ( + + }> + + + + + + } /> + } /> + } + /> + + } + /> + } + /> + } + /> + } /> + + {/* Admin */} + } + /> + + } + /> + } + /> + + } + /> + + } + /> + } + /> + } + /> + + } + /> + + } + /> + } + /> + } + /> + {/* Manager */} + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + + } + /> + } + /> + } + /> + } + /> + } + /> + {/* Onboarding Flow */} + } /> + } + /> + + {/* Experimental feature pages */} + {/* Live Document Sync feature */} + } + /> + + } + /> + + } + /> + } + /> + + } + /> + + + + + + + + + + ); +} diff --git a/frontend/src/AuthContext.jsx b/frontend/src/AuthContext.jsx new file mode 100644 index 0000000000000000000000000000000000000000..34ec0cff7e6aeec212e11508b9cf6331d0c168b6 --- /dev/null +++ b/frontend/src/AuthContext.jsx @@ -0,0 +1,32 @@ +import React, { useState, createContext } from "react"; +import { AUTH_TIMESTAMP, AUTH_TOKEN, AUTH_USER } from "@/utils/constants"; + +export const AuthContext = createContext(null); +export function ContextWrapper(props) { + const localUser = localStorage.getItem(AUTH_USER); + const localAuthToken = localStorage.getItem(AUTH_TOKEN); + const [store, setStore] = useState({ + user: localUser ? JSON.parse(localUser) : null, + authToken: localAuthToken ? localAuthToken : null, + }); + + const [actions] = useState({ + updateUser: (user, authToken = "") => { + localStorage.setItem(AUTH_USER, JSON.stringify(user)); + localStorage.setItem(AUTH_TOKEN, authToken); + setStore({ user, authToken }); + }, + unsetUser: () => { + localStorage.removeItem(AUTH_USER); + localStorage.removeItem(AUTH_TOKEN); + localStorage.removeItem(AUTH_TIMESTAMP); + setStore({ user: null, authToken: null }); + }, + }); + + return ( + + {props.children} + + ); +} diff --git a/frontend/src/LogoContext.jsx b/frontend/src/LogoContext.jsx new file mode 100644 index 0000000000000000000000000000000000000000..3bf499da76ed2513bd4c7abb32481b6d130cb24a --- /dev/null +++ b/frontend/src/LogoContext.jsx @@ -0,0 +1,57 @@ +import { createContext, useEffect, useState } from "react"; +import AnythingLLM from "./media/logo/anything-llm.png"; +import AnythingLLMDark from "./media/logo/anything-llm-dark.png"; +import DefaultLoginLogoLight from "./media/illustrations/login-logo.svg"; +import DefaultLoginLogoDark from "./media/illustrations/login-logo-light.svg"; +import System from "./models/system"; + +export const REFETCH_LOGO_EVENT = "refetch-logo"; +export const LogoContext = createContext(); + +export function LogoProvider({ children }) { + const [logo, setLogo] = useState(""); + const [loginLogo, setLoginLogo] = useState(""); + const [isCustomLogo, setIsCustomLogo] = useState(false); + const DefaultLoginLogo = + localStorage.getItem("theme") !== "default" + ? DefaultLoginLogoDark + : DefaultLoginLogoLight; + + async function fetchInstanceLogo() { + try { + const { isCustomLogo, logoURL } = await System.fetchLogo(); + if (logoURL) { + setLogo(logoURL); + setLoginLogo(isCustomLogo ? logoURL : DefaultLoginLogo); + setIsCustomLogo(isCustomLogo); + } else { + localStorage.getItem("theme") !== "default" + ? setLogo(AnythingLLMDark) + : setLogo(AnythingLLM); + setLoginLogo(DefaultLoginLogo); + setIsCustomLogo(false); + } + } catch (err) { + localStorage.getItem("theme") !== "default" + ? setLogo(AnythingLLMDark) + : setLogo(AnythingLLM); + setLoginLogo(DefaultLoginLogo); + setIsCustomLogo(false); + console.error("Failed to fetch logo:", err); + } + } + + useEffect(() => { + fetchInstanceLogo(); + window.addEventListener(REFETCH_LOGO_EVENT, fetchInstanceLogo); + return () => { + window.removeEventListener(REFETCH_LOGO_EVENT, fetchInstanceLogo); + }; + }, []); + + return ( + + {children} + + ); +} diff --git a/frontend/src/PfpContext.jsx b/frontend/src/PfpContext.jsx new file mode 100644 index 0000000000000000000000000000000000000000..3d60d559d2b26044f2ad101feab20700fa88f474 --- /dev/null +++ b/frontend/src/PfpContext.jsx @@ -0,0 +1,30 @@ +import React, { createContext, useState, useEffect } from "react"; +import useUser from "./hooks/useUser"; +import System from "./models/system"; + +export const PfpContext = createContext(); + +export function PfpProvider({ children }) { + const [pfp, setPfp] = useState(null); + const { user } = useUser(); + + useEffect(() => { + async function fetchPfp() { + if (!user?.id) return; + try { + const pfpUrl = await System.fetchPfp(user.id); + setPfp(pfpUrl); + } catch (err) { + setPfp(null); + console.error("Failed to fetch pfp:", err); + } + } + fetchPfp(); + }, [user?.id]); + + return ( + + {children} + + ); +} diff --git a/frontend/src/ThemeContext.jsx b/frontend/src/ThemeContext.jsx new file mode 100644 index 0000000000000000000000000000000000000000..f9a5c685fda6f26ffba77eaf6fa72dc03f9a73fd --- /dev/null +++ b/frontend/src/ThemeContext.jsx @@ -0,0 +1,16 @@ +import React, { createContext, useContext } from "react"; +import { useTheme } from "./hooks/useTheme"; + +const ThemeContext = createContext(); + +export function ThemeProvider({ children }) { + const themeValue = useTheme(); + + return ( + {children} + ); +} + +export function useThemeContext() { + return useContext(ThemeContext); +} diff --git a/frontend/src/components/CanViewChatHistory/index.jsx b/frontend/src/components/CanViewChatHistory/index.jsx new file mode 100644 index 0000000000000000000000000000000000000000..44e75353147fc3cbd9df21ce2907c2bf7aaf24a0 --- /dev/null +++ b/frontend/src/components/CanViewChatHistory/index.jsx @@ -0,0 +1,50 @@ +import { useEffect, useState } from "react"; +import { FullScreenLoader } from "@/components/Preloader"; +import System from "@/models/system"; +import paths from "@/utils/paths"; + +/** + * Protects the view from system set ups who cannot view chat history. + * If the user cannot view chat history, they are redirected to the home page. + * @param {React.ReactNode} children + */ +export function CanViewChatHistory({ children }) { + const { loading, viewable } = useCanViewChatHistory(); + if (loading) return ; + if (!viewable) { + window.location.href = paths.home(); + return ; + } + + return <>{children}; +} + +/** + * Provides the `viewable` state to the children. + * @returns {React.ReactNode} + */ +export function CanViewChatHistoryProvider({ children }) { + const { loading, viewable } = useCanViewChatHistory(); + if (loading) return null; + return <>{children({ viewable })}; +} + +/** + * Hook that fetches the can view chat history state from local storage or the system settings. + * @returns {Promise<{viewable: boolean, error: string | null}>} + */ +export function useCanViewChatHistory() { + const [loading, setLoading] = useState(true); + const [viewable, setViewable] = useState(false); + + useEffect(() => { + async function fetchViewable() { + const { viewable } = await System.fetchCanViewChatHistory(); + setViewable(viewable); + setLoading(false); + } + fetchViewable(); + }, []); + + return { loading, viewable }; +} diff --git a/frontend/src/components/ChangeWarning/index.jsx b/frontend/src/components/ChangeWarning/index.jsx new file mode 100644 index 0000000000000000000000000000000000000000..95ca1c49ff718c747648ddaf4fdfd6a5de1415e8 --- /dev/null +++ b/frontend/src/components/ChangeWarning/index.jsx @@ -0,0 +1,61 @@ +import { Warning, X } from "@phosphor-icons/react"; + +export default function ChangeWarningModal({ + warningText = "", + onClose, + onConfirm, +}) { + return ( +
+
+
+ +

+ WARNING - This action is irreversible +

+
+ +
+
+
+

+ {warningText.split("\\n").map((line, index) => ( + + {line} +
+
+ ))} +
+
+ Are you sure you want to proceed? +

+
+
+
+ + +
+
+ ); +} diff --git a/frontend/src/components/ChatBubble/index.jsx b/frontend/src/components/ChatBubble/index.jsx new file mode 100644 index 0000000000000000000000000000000000000000..7b37cd5d17e540e43e65b134a7d3958fa2a8b95c --- /dev/null +++ b/frontend/src/components/ChatBubble/index.jsx @@ -0,0 +1,31 @@ +import React from "react"; +import UserIcon from "../UserIcon"; +import { userFromStorage } from "@/utils/request"; +import renderMarkdown from "@/utils/chat/markdown"; +import DOMPurify from "@/utils/chat/purify"; + +export default function ChatBubble({ message, type, popMsg }) { + const isUser = type === "user"; + + return ( +
+
+
+ + +
+
+
+
+ ); +} diff --git a/frontend/src/components/CommunityHub/PublishEntityModal/AgentFlows/index.jsx b/frontend/src/components/CommunityHub/PublishEntityModal/AgentFlows/index.jsx new file mode 100644 index 0000000000000000000000000000000000000000..05ace1ac828812459069b6db6bf4413ea2684aee --- /dev/null +++ b/frontend/src/components/CommunityHub/PublishEntityModal/AgentFlows/index.jsx @@ -0,0 +1,261 @@ +import { useState, useRef } from "react"; +import { useTranslation } from "react-i18next"; +import CommunityHub from "@/models/communityHub"; +import showToast from "@/utils/toast"; +import paths from "@/utils/paths"; +import { X, CaretRight } from "@phosphor-icons/react"; +import { BLOCK_INFO } from "@/pages/Admin/AgentBuilder/BlockList"; +import { Link } from "react-router-dom"; + +export default function AgentFlows({ entity }) { + const { t } = useTranslation(); + const formRef = useRef(null); + const [isSubmitting, setIsSubmitting] = useState(false); + const [tags, setTags] = useState([]); + const [tagInput, setTagInput] = useState(""); + const [isSuccess, setIsSuccess] = useState(false); + const [itemId, setItemId] = useState(null); + const [expandedStep, setExpandedStep] = useState(null); + + const handleSubmit = async (e) => { + e.preventDefault(); + e.stopPropagation(); + setIsSubmitting(true); + try { + const form = new FormData(formRef.current); + const data = { + name: form.get("name"), + description: form.get("description"), + tags: tags, + visibility: "private", + flow: JSON.stringify({ + name: form.get("name"), + description: form.get("description"), + steps: entity.steps, + tags: tags, + visibility: "private", + }), + }; + const { success, error, itemId } = + await CommunityHub.createAgentFlow(data); + if (!success) throw new Error(error); + setItemId(itemId); + setIsSuccess(true); + } catch (error) { + console.error("Failed to publish agent flow:", error); + showToast(`Failed to publish agent flow: ${error.message}`, "error", { + clear: true, + }); + } finally { + setIsSubmitting(false); + } + }; + + const handleKeyDown = (e) => { + if (e.key === "Enter" || e.key === ",") { + e.preventDefault(); + const value = tagInput.trim(); + if (value.length > 20) return; + if (value && !tags.includes(value)) { + setTags((prevTags) => [...prevTags, value].slice(0, 5)); // Limit to 5 tags + setTagInput(""); + } + } + }; + + const removeTag = (tagToRemove) => { + setTags(tags.filter((tag) => tag !== tagToRemove)); + }; + + if (isSuccess) { + return ( +
+
+

+ {t("community_hub.publish.agent_flow.success_title")} +

+

+ {t("community_hub.publish.agent_flow.success_description")} +

+

+ {t("community_hub.publish.agent_flow.success_thank_you")} +

+ + {t("community_hub.publish.agent_flow.view_on_hub")} + +
+
+ ); + } + + return ( + <> +
+

+ {t("community_hub.publish.agent_flow.modal_title")} +

+
+
+
+
+ +
+ {t("community_hub.publish.agent_flow.name_description")} +
+ +
+ +
+ +
+ {t("community_hub.publish.agent_flow.description_description")} +
+ +
+
+ + +
+
+
+
+ + +
+ + + + + ); +} diff --git a/frontend/src/components/WorkspaceChat/ChatContainer/PromptInput/SlashCommands/SlashPresets/EditPresetModal.jsx b/frontend/src/components/WorkspaceChat/ChatContainer/PromptInput/SlashCommands/SlashPresets/EditPresetModal.jsx new file mode 100644 index 0000000000000000000000000000000000000000..c50c304635cf25e2be512a0bcc72bedb6969d26c --- /dev/null +++ b/frontend/src/components/WorkspaceChat/ChatContainer/PromptInput/SlashCommands/SlashPresets/EditPresetModal.jsx @@ -0,0 +1,155 @@ +import { useState, useEffect } from "react"; +import { X } from "@phosphor-icons/react"; +import ModalWrapper from "@/components/ModalWrapper"; +import { CMD_REGEX } from "."; + +export default function EditPresetModal({ + isOpen, + onClose, + onSave, + onDelete, + preset, +}) { + const [command, setCommand] = useState(""); + const [deleting, setDeleting] = useState(false); + + useEffect(() => { + if (preset && isOpen) { + setCommand(preset.command?.slice(1) || ""); + } + }, [preset, isOpen]); + + const handleSubmit = (e) => { + e.preventDefault(); + const form = new FormData(e.target); + const sanitizedCommand = command.replace(CMD_REGEX, ""); + onSave({ + id: preset.id, + command: `/${sanitizedCommand}`, + prompt: form.get("prompt"), + description: form.get("description"), + }); + }; + + const handleCommandChange = (e) => { + const value = e.target.value.replace(CMD_REGEX, ""); + setCommand(value); + }; + + const handleDelete = async () => { + if (!window.confirm("Are you sure you want to delete this preset?")) return; + + setDeleting(true); + await onDelete(preset.id); + setDeleting(false); + onClose(); + }; + + return ( + +
+
+
+

+ Edit Preset +

+
+ +
+
+
+
+
+
+ +
+ / + +
+
+
+ + +
+
+ + +
+
+
+
+ +
+ + +
+
+
+
+
+
+ ); +} diff --git a/frontend/src/components/WorkspaceChat/ChatContainer/PromptInput/SlashCommands/SlashPresets/index.jsx b/frontend/src/components/WorkspaceChat/ChatContainer/PromptInput/SlashCommands/SlashPresets/index.jsx new file mode 100644 index 0000000000000000000000000000000000000000..d38378536ab2eff73f3c5ae11f001721e0ebb837 --- /dev/null +++ b/frontend/src/components/WorkspaceChat/ChatContainer/PromptInput/SlashCommands/SlashPresets/index.jsx @@ -0,0 +1,244 @@ +import { useEffect, useState, useRef } from "react"; +import { useIsAgentSessionActive } from "@/utils/chat/agent"; +import AddPresetModal from "./AddPresetModal"; +import EditPresetModal from "./EditPresetModal"; +import { useModal } from "@/hooks/useModal"; +import System from "@/models/system"; +import { DotsThree, Plus } from "@phosphor-icons/react"; +import showToast from "@/utils/toast"; +import { useSearchParams } from "react-router-dom"; +import { useTranslation } from "react-i18next"; +import PublishEntityModal from "@/components/CommunityHub/PublishEntityModal"; + +export const CMD_REGEX = new RegExp(/[^a-zA-Z0-9_-]/g); +export default function SlashPresets({ setShowing, sendCommand, promptRef }) { + const { t } = useTranslation(); + const isActiveAgentSession = useIsAgentSessionActive(); + const { + isOpen: isAddModalOpen, + openModal: openAddModal, + closeModal: closeAddModal, + } = useModal(); + const { + isOpen: isEditModalOpen, + openModal: openEditModal, + closeModal: closeEditModal, + } = useModal(); + const { + isOpen: isPublishModalOpen, + openModal: openPublishModal, + closeModal: closePublishModal, + } = useModal(); + const [presets, setPresets] = useState([]); + const [selectedPreset, setSelectedPreset] = useState(null); + const [presetToPublish, setPresetToPublish] = useState(null); + const [searchParams] = useSearchParams(); + + useEffect(() => { + fetchPresets(); + }, []); + + /* + * @checklist-item + * If the URL has the slash-commands param, open the add modal for the user + * automatically when the component mounts. + */ + useEffect(() => { + if ( + searchParams.get("action") === "open-new-slash-command-modal" && + !isAddModalOpen + ) + openAddModal(); + }, []); + + if (isActiveAgentSession) return null; + + const fetchPresets = async () => { + const presets = await System.getSlashCommandPresets(); + setPresets(presets); + }; + + const handleSavePreset = async (preset) => { + const { error } = await System.createSlashCommandPreset(preset); + if (!!error) { + showToast(error, "error"); + return false; + } + + fetchPresets(); + closeAddModal(); + return true; + }; + + const handleEditPreset = (preset) => { + setSelectedPreset(preset); + openEditModal(); + }; + + const handleUpdatePreset = async (updatedPreset) => { + const { error } = await System.updateSlashCommandPreset( + updatedPreset.id, + updatedPreset + ); + + if (!!error) { + showToast(error, "error"); + return; + } + + fetchPresets(); + closeEditModalAndResetPreset(); + }; + + const handleDeletePreset = async (presetId) => { + await System.deleteSlashCommandPreset(presetId); + fetchPresets(); + closeEditModalAndResetPreset(); + }; + + const closeEditModalAndResetPreset = () => { + closeEditModal(); + setSelectedPreset(null); + }; + + const handlePublishPreset = (preset) => { + setPresetToPublish({ + name: preset.command.slice(1), + description: preset.description, + command: preset.command, + prompt: preset.prompt, + }); + openPublishModal(); + }; + + return ( + <> + {presets.map((preset) => ( + { + setShowing(false); + sendCommand({ text: `${preset.command} ` }); + promptRef?.current?.focus(); + }} + onEdit={handleEditPreset} + onPublish={handlePublishPreset} + /> + ))} + + + {selectedPreset && ( + + )} + + + ); +} + +function PresetItem({ preset, onUse, onEdit, onPublish }) { + const [showMenu, setShowMenu] = useState(false); + const menuRef = useRef(null); + const menuButtonRef = useRef(null); + + useEffect(() => { + const handleClickOutside = (event) => { + if ( + showMenu && + menuRef.current && + !menuRef.current.contains(event.target) && + menuButtonRef.current && + !menuButtonRef.current.contains(event.target) + ) { + setShowMenu(false); + } + }; + document.addEventListener("mousedown", handleClickOutside); + return () => { + document.removeEventListener("mousedown", handleClickOutside); + }; + }, [showMenu]); + + return ( + + {showMenu && ( +
+ + +
+ )} + + ); +} diff --git a/frontend/src/components/WorkspaceChat/ChatContainer/PromptInput/SlashCommands/endAgentSession.jsx b/frontend/src/components/WorkspaceChat/ChatContainer/PromptInput/SlashCommands/endAgentSession.jsx new file mode 100644 index 0000000000000000000000000000000000000000..bc07c864ba72fb3dbd9f8eb6b0565f39b9b7f316 --- /dev/null +++ b/frontend/src/components/WorkspaceChat/ChatContainer/PromptInput/SlashCommands/endAgentSession.jsx @@ -0,0 +1,23 @@ +import { useIsAgentSessionActive } from "@/utils/chat/agent"; + +export default function EndAgentSession({ setShowing, sendCommand }) { + const isActiveAgentSession = useIsAgentSessionActive(); + if (!isActiveAgentSession) return null; + + return ( + + ); +} diff --git a/frontend/src/components/WorkspaceChat/ChatContainer/PromptInput/SlashCommands/icons/SlashCommandIcon.jsx b/frontend/src/components/WorkspaceChat/ChatContainer/PromptInput/SlashCommands/icons/SlashCommandIcon.jsx new file mode 100644 index 0000000000000000000000000000000000000000..4805233eef3ef0713166f5dd66d654ea036ee7c8 --- /dev/null +++ b/frontend/src/components/WorkspaceChat/ChatContainer/PromptInput/SlashCommands/icons/SlashCommandIcon.jsx @@ -0,0 +1,28 @@ +export default function SlashCommandIcon(props) { + return ( + + + + + ); +} diff --git a/frontend/src/components/WorkspaceChat/ChatContainer/PromptInput/SlashCommands/index.jsx b/frontend/src/components/WorkspaceChat/ChatContainer/PromptInput/SlashCommands/index.jsx new file mode 100644 index 0000000000000000000000000000000000000000..d0b52bea88ef845c90cb71a2e71505491645d723 --- /dev/null +++ b/frontend/src/components/WorkspaceChat/ChatContainer/PromptInput/SlashCommands/index.jsx @@ -0,0 +1,75 @@ +import { useEffect, useRef, useState } from "react"; +import SlashCommandIcon from "./icons/SlashCommandIcon"; +import { Tooltip } from "react-tooltip"; +import ResetCommand from "./reset"; +import EndAgentSession from "./endAgentSession"; +import SlashPresets from "./SlashPresets"; +import { useTranslation } from "react-i18next"; + +export default function SlashCommandsButton({ showing, setShowSlashCommand }) { + const { t } = useTranslation(); + return ( +
setShowSlashCommand(!showing)} + className={`flex justify-center items-center cursor-pointer ${ + showing ? "!opacity-100" : "" + }`} + > + + +
+ ); +} + +export function SlashCommands({ showing, setShowing, sendCommand, promptRef }) { + const cmdRef = useRef(null); + useEffect(() => { + function listenForOutsideClick() { + if (!showing || !cmdRef.current) return false; + document.addEventListener("click", closeIfOutside); + } + listenForOutsideClick(); + }, [showing, cmdRef.current]); + + const closeIfOutside = ({ target }) => { + if (target.id === "slash-cmd-btn") return; + const isOutside = !cmdRef?.current?.contains(target); + if (!isOutside) return; + setShowing(false); + }; + + return ( + + ); +} + +export function useSlashCommands() { + const [showSlashCommand, setShowSlashCommand] = useState(false); + return { showSlashCommand, setShowSlashCommand }; +} diff --git a/frontend/src/components/WorkspaceChat/ChatContainer/PromptInput/SlashCommands/reset.jsx b/frontend/src/components/WorkspaceChat/ChatContainer/PromptInput/SlashCommands/reset.jsx new file mode 100644 index 0000000000000000000000000000000000000000..94f54b1b0d709ffef517ef4b1d520ec4aea2434d --- /dev/null +++ b/frontend/src/components/WorkspaceChat/ChatContainer/PromptInput/SlashCommands/reset.jsx @@ -0,0 +1,27 @@ +import { useIsAgentSessionActive } from "@/utils/chat/agent"; +import { useTranslation } from "react-i18next"; + +export default function ResetCommand({ setShowing, sendCommand }) { + const { t } = useTranslation(); + const isActiveAgentSession = useIsAgentSessionActive(); + if (isActiveAgentSession) return null; // cannot reset during active agent chat + + return ( + + ); +} diff --git a/frontend/src/components/WorkspaceChat/ChatContainer/PromptInput/SpeechToText/index.jsx b/frontend/src/components/WorkspaceChat/ChatContainer/PromptInput/SpeechToText/index.jsx new file mode 100644 index 0000000000000000000000000000000000000000..9e701b8535108c74b8cf27dbd44180ec444c961f --- /dev/null +++ b/frontend/src/components/WorkspaceChat/ChatContainer/PromptInput/SpeechToText/index.jsx @@ -0,0 +1,147 @@ +import { useEffect, useCallback, useRef } from "react"; +import { Microphone } from "@phosphor-icons/react"; +import { Tooltip } from "react-tooltip"; +import _regeneratorRuntime from "regenerator-runtime"; +import SpeechRecognition, { + useSpeechRecognition, +} from "react-speech-recognition"; +import { PROMPT_INPUT_EVENT } from "../../PromptInput"; +import { useTranslation } from "react-i18next"; +import Appearance from "@/models/appearance"; + +let timeout; +const SILENCE_INTERVAL = 3_200; // wait in seconds of silence before closing. + +/** + * Speech-to-text input component for the chat window. + * @param {Object} props - The component props + * @param {(textToAppend: string, autoSubmit: boolean) => void} props.sendCommand - The function to send the command + * @returns {React.ReactElement} The SpeechToText component + */ +export default function SpeechToText({ sendCommand }) { + const previousTranscriptRef = useRef(""); + const { + transcript, + listening, + resetTranscript, + browserSupportsSpeechRecognition, + browserSupportsContinuousListening, + isMicrophoneAvailable, + } = useSpeechRecognition({ + clearTranscriptOnListen: true, + }); + const { t } = useTranslation(); + function startSTTSession() { + if (!isMicrophoneAvailable) { + alert( + "AnythingLLM does not have access to microphone. Please enable for this site to use this feature." + ); + return; + } + + resetTranscript(); + previousTranscriptRef.current = ""; + SpeechRecognition.startListening({ + continuous: browserSupportsContinuousListening, + language: window?.navigator?.language ?? "en-US", + }); + } + + function endSTTSession() { + SpeechRecognition.stopListening(); + + // If auto submit is enabled, send an empty string to the chat window to submit the current transcript + // since every chunk of text should have been streamed to the chat window by now. + if (Appearance.get("autoSubmitSttInput")) { + sendCommand({ + text: "", + autoSubmit: true, + writeMode: "append", + }); + } + + resetTranscript(); + previousTranscriptRef.current = ""; + clearTimeout(timeout); + } + + const handleKeyPress = useCallback( + (event) => { + // CTRL + m on Mac and Windows to toggle STT listening + if (event.ctrlKey && event.keyCode === 77) { + if (listening) { + endSTTSession(); + } else { + startSTTSession(); + } + } + }, + [listening, endSTTSession, startSTTSession] + ); + + function handlePromptUpdate(e) { + if (!e?.detail && timeout) { + endSTTSession(); + clearTimeout(timeout); + } + } + + useEffect(() => { + document.addEventListener("keydown", handleKeyPress); + return () => { + document.removeEventListener("keydown", handleKeyPress); + }; + }, [handleKeyPress]); + + useEffect(() => { + if (!!window) + window.addEventListener(PROMPT_INPUT_EVENT, handlePromptUpdate); + return () => + window?.removeEventListener(PROMPT_INPUT_EVENT, handlePromptUpdate); + }, []); + + useEffect(() => { + if (transcript?.length > 0 && listening) { + const previousTranscript = previousTranscriptRef.current; + const newContent = transcript.slice(previousTranscript.length); + + // Stream just the diff of the new content since transcript is an accumulating string. + // and not just the new content transcribed. + if (newContent.length > 0) + sendCommand({ text: newContent, writeMode: "append" }); + + previousTranscriptRef.current = transcript; + clearTimeout(timeout); + timeout = setTimeout(() => { + endSTTSession(); + }, SILENCE_INTERVAL); + } + }, [transcript, listening]); + + if (!browserSupportsSpeechRecognition) return null; + return ( +
+ + +
+ ); +} diff --git a/frontend/src/components/WorkspaceChat/ChatContainer/PromptInput/StopGenerationButton/index.jsx b/frontend/src/components/WorkspaceChat/ChatContainer/PromptInput/StopGenerationButton/index.jsx new file mode 100644 index 0000000000000000000000000000000000000000..bce3c684293892d27063b8b74f179ecbc0836e0d --- /dev/null +++ b/frontend/src/components/WorkspaceChat/ChatContainer/PromptInput/StopGenerationButton/index.jsx @@ -0,0 +1,53 @@ +import { ABORT_STREAM_EVENT } from "@/utils/chat"; +import { Tooltip } from "react-tooltip"; + +export default function StopGenerationButton() { + function emitHaltEvent() { + window.dispatchEvent(new CustomEvent(ABORT_STREAM_EVENT)); + } + + return ( + <> + + + + ); +} diff --git a/frontend/src/components/WorkspaceChat/ChatContainer/PromptInput/StopGenerationButton/stop.svg b/frontend/src/components/WorkspaceChat/ChatContainer/PromptInput/StopGenerationButton/stop.svg new file mode 100644 index 0000000000000000000000000000000000000000..ab98895c264d71ba2bcc5279d4dac0046496bfaa --- /dev/null +++ b/frontend/src/components/WorkspaceChat/ChatContainer/PromptInput/StopGenerationButton/stop.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/src/components/WorkspaceChat/ChatContainer/PromptInput/TextSizeMenu/index.jsx b/frontend/src/components/WorkspaceChat/ChatContainer/PromptInput/TextSizeMenu/index.jsx new file mode 100644 index 0000000000000000000000000000000000000000..d2a2359340fa89514b0bad5311c5d9a2f33350fc --- /dev/null +++ b/frontend/src/components/WorkspaceChat/ChatContainer/PromptInput/TextSizeMenu/index.jsx @@ -0,0 +1,119 @@ +import { useState, useRef } from "react"; +import { TextT } from "@phosphor-icons/react"; +import { Tooltip } from "react-tooltip"; +import { useTranslation } from "react-i18next"; +import { useTheme } from "@/hooks/useTheme"; + +export default function TextSizeButton() { + const tooltipRef = useRef(null); + const { t } = useTranslation(); + const { theme } = useTheme(); + + const toggleTooltip = () => { + if (!tooltipRef.current) return; + tooltipRef.current.isOpen + ? tooltipRef.current.close() + : tooltipRef.current.open(); + }; + + return ( + <> +
+ +
+ + + + + ); +} + +function TextSizeMenu({ tooltipRef }) { + const { t } = useTranslation(); + const [selectedSize, setSelectedSize] = useState( + window.localStorage.getItem("anythingllm_text_size") || "normal" + ); + + const handleTextSizeChange = (size) => { + setSelectedSize(size); + window.localStorage.setItem("anythingllm_text_size", size); + window.dispatchEvent(new CustomEvent("textSizeChange", { detail: size })); + tooltipRef.current?.close(); + }; + + return ( +
+ + + + + +
+ ); +} diff --git a/frontend/src/components/WorkspaceChat/ChatContainer/PromptInput/index.jsx b/frontend/src/components/WorkspaceChat/ChatContainer/PromptInput/index.jsx new file mode 100644 index 0000000000000000000000000000000000000000..8a498f0b35093d4f77f898e9ff1949fecd9b0cd8 --- /dev/null +++ b/frontend/src/components/WorkspaceChat/ChatContainer/PromptInput/index.jsx @@ -0,0 +1,377 @@ +import React, { useState, useRef, useEffect } from "react"; +import SlashCommandsButton, { + SlashCommands, + useSlashCommands, +} from "./SlashCommands"; +import debounce from "lodash.debounce"; +import { PaperPlaneRight } from "@phosphor-icons/react"; +import StopGenerationButton from "./StopGenerationButton"; +import AvailableAgentsButton, { + AvailableAgents, + useAvailableAgents, +} from "./AgentMenu"; +import TextSizeButton from "./TextSizeMenu"; +import LLMSelectorAction from "./LLMSelector/action"; +import SpeechToText from "./SpeechToText"; +import { Tooltip } from "react-tooltip"; +import AttachmentManager from "./Attachments"; +import AttachItem from "./AttachItem"; +import { + ATTACHMENTS_PROCESSED_EVENT, + ATTACHMENTS_PROCESSING_EVENT, + PASTE_ATTACHMENT_EVENT, +} from "../DnDWrapper"; +import useTextSize from "@/hooks/useTextSize"; +import { useTranslation } from "react-i18next"; +import Appearance from "@/models/appearance"; + +export const PROMPT_INPUT_ID = "primary-prompt-input"; +export const PROMPT_INPUT_EVENT = "set_prompt_input"; +const MAX_EDIT_STACK_SIZE = 100; + +export default function PromptInput({ + submit, + onChange, + isStreaming, + sendCommand, + attachments = [], +}) { + const { t } = useTranslation(); + const { isDisabled } = useIsDisabled(); + const [promptInput, setPromptInput] = useState(""); + const { showAgents, setShowAgents } = useAvailableAgents(); + const { showSlashCommand, setShowSlashCommand } = useSlashCommands(); + const formRef = useRef(null); + const textareaRef = useRef(null); + const [_, setFocused] = useState(false); + const undoStack = useRef([]); + const redoStack = useRef([]); + const { textSizeClass } = useTextSize(); + + /** + * To prevent too many re-renders we remotely listen for updates from the parent + * via an event cycle. Otherwise, using message as a prop leads to a re-render every + * change on the input. + * @param {{detail: {messageContent: string, writeMode: 'replace' | 'append'}}} e + */ + function handlePromptUpdate(e) { + const { messageContent, writeMode = "replace" } = e?.detail ?? {}; + if (writeMode === "append") setPromptInput((prev) => prev + messageContent); + else setPromptInput(messageContent ?? ""); + } + + useEffect(() => { + if (!!window) + window.addEventListener(PROMPT_INPUT_EVENT, handlePromptUpdate); + return () => + window?.removeEventListener(PROMPT_INPUT_EVENT, handlePromptUpdate); + }, []); + + useEffect(() => { + if (!isStreaming && textareaRef.current) textareaRef.current.focus(); + resetTextAreaHeight(); + }, [isStreaming]); + + /** + * Save the current state before changes + * @param {number} adjustment + */ + function saveCurrentState(adjustment = 0) { + if (undoStack.current.length >= MAX_EDIT_STACK_SIZE) + undoStack.current.shift(); + undoStack.current.push({ + value: promptInput, + cursorPositionStart: textareaRef.current.selectionStart + adjustment, + cursorPositionEnd: textareaRef.current.selectionEnd + adjustment, + }); + } + const debouncedSaveState = debounce(saveCurrentState, 250); + + function handleSubmit(e) { + setFocused(false); + submit(e); + } + + function resetTextAreaHeight() { + if (!textareaRef.current) return; + textareaRef.current.style.height = "auto"; + } + + function checkForSlash(e) { + const input = e.target.value; + if (input === "/") setShowSlashCommand(true); + if (showSlashCommand) setShowSlashCommand(false); + return; + } + const watchForSlash = debounce(checkForSlash, 300); + + function checkForAt(e) { + const input = e.target.value; + if (input === "@") return setShowAgents(true); + if (showAgents) return setShowAgents(false); + } + const watchForAt = debounce(checkForAt, 300); + + /** + * Capture enter key press to handle submission, redo, or undo + * via keyboard shortcuts + * @param {KeyboardEvent} event + */ + function captureEnterOrUndo(event) { + // Is simple enter key press w/o shift key + if (event.keyCode === 13 && !event.shiftKey) { + event.preventDefault(); + if (isStreaming || isDisabled) return; // Prevent submission if streaming or disabled + return submit(event); + } + + // Is undo with Ctrl+Z or Cmd+Z + Shift key = Redo + if ( + (event.ctrlKey || event.metaKey) && + event.key === "z" && + event.shiftKey + ) { + event.preventDefault(); + if (redoStack.current.length === 0) return; + + const nextState = redoStack.current.pop(); + if (!nextState) return; + + undoStack.current.push({ + value: promptInput, + cursorPositionStart: textareaRef.current.selectionStart, + cursorPositionEnd: textareaRef.current.selectionEnd, + }); + setPromptInput(nextState.value); + setTimeout(() => { + textareaRef.current.setSelectionRange( + nextState.cursorPositionStart, + nextState.cursorPositionEnd + ); + }, 0); + } + + // Undo with Ctrl+Z or Cmd+Z + if ( + (event.ctrlKey || event.metaKey) && + event.key === "z" && + !event.shiftKey + ) { + if (undoStack.current.length === 0) return; + const lastState = undoStack.current.pop(); + if (!lastState) return; + + redoStack.current.push({ + value: promptInput, + cursorPositionStart: textareaRef.current.selectionStart, + cursorPositionEnd: textareaRef.current.selectionEnd, + }); + setPromptInput(lastState.value); + setTimeout(() => { + textareaRef.current.setSelectionRange( + lastState.cursorPositionStart, + lastState.cursorPositionEnd + ); + }, 0); + } + } + + function adjustTextArea(event) { + const element = event.target; + element.style.height = "auto"; + element.style.height = `${element.scrollHeight}px`; + } + + function handlePasteEvent(e) { + e.preventDefault(); + if (e.clipboardData.items.length === 0) return false; + + // paste any clipboard items that are images. + for (const item of e.clipboardData.items) { + if (item.type.startsWith("image/")) { + const file = item.getAsFile(); + window.dispatchEvent( + new CustomEvent(PASTE_ATTACHMENT_EVENT, { + detail: { files: [file] }, + }) + ); + continue; + } + + // handle files specifically that are not images as uploads + if (item.kind === "file") { + const file = item.getAsFile(); + window.dispatchEvent( + new CustomEvent(PASTE_ATTACHMENT_EVENT, { + detail: { files: [file] }, + }) + ); + continue; + } + } + + const pasteText = e.clipboardData.getData("text/plain"); + if (pasteText) { + const textarea = textareaRef.current; + const start = textarea.selectionStart; + const end = textarea.selectionEnd; + const newPromptInput = + promptInput.substring(0, start) + + pasteText + + promptInput.substring(end); + setPromptInput(newPromptInput); + onChange({ target: { value: newPromptInput } }); + + // Set the cursor position after the pasted text + // we need to use setTimeout to prevent the cursor from being set to the end of the text + setTimeout(() => { + textarea.selectionStart = textarea.selectionEnd = + start + pasteText.length; + adjustTextArea({ target: textarea }); + }, 0); + } + return; + } + + function handleChange(e) { + debouncedSaveState(-1); + onChange(e); + watchForSlash(e); + watchForAt(e); + adjustTextArea(e); + setPromptInput(e.target.value); + } + + return ( +
+ + +
+
+
+ +
+