diff --git a/.github/codeql.yml b/.github/codeql.yml index 79584b9d3..b21ddec01 100644 --- a/.github/codeql.yml +++ b/.github/codeql.yml @@ -6,5 +6,8 @@ paths: - src/ui - src/common paths-ignore: - - src/ui/static + - src/ui/static/js/tsparticles.bundle.min.js + - src/ui/static/js/editor + - src/ui/static/js/utils/flatpickr.js + - src/ui/static/js/utils/purify - src/common/core/modsecurity/files diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 000000000..a597aa373 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,31 @@ +name: CodeQL Analysis + +on: + schedule: + # Weekly on Saturdays. + - cron: "30 1 * * 6" + workflow_call: + +jobs: + code-security: + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + strategy: + fail-fast: false + matrix: + language: ["python", "javascript"] + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + config-file: ./.github/codeql.yml + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: "/language:${{matrix.language}}" diff --git a/.github/workflows/dev.yml b/.github/workflows/dev.yml index 001bcc040..4d4261414 100644 --- a/.github/workflows/dev.yml +++ b/.github/workflows/dev.yml @@ -63,45 +63,28 @@ jobs: DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} DOCKER_TOKEN: ${{ secrets.DOCKER_TOKEN }} - # Python code security - code-security: - runs-on: ubuntu-latest + codeql: + uses: ./.github/workflows/codeql.yml permissions: actions: read contents: read security-events: write - strategy: - fail-fast: false - matrix: - language: ["python"] - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - languages: ${{ matrix.language }} - config-file: ./.github/codeql.yml - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 - with: - category: "/language:${{matrix.language}}" # UI tests tests-ui: - needs: [code-security, build-containers] + needs: [codeql, build-containers] uses: ./.github/workflows/tests-ui.yml with: RELEASE: dev tests-ui-linux: - needs: [code-security, build-packages] + needs: [codeql, build-packages] uses: ./.github/workflows/tests-ui-linux.yml with: RELEASE: dev # Core tests prepare-tests-core: - needs: [code-security, build-containers, build-packages] + needs: [codeql, build-containers, build-packages] runs-on: ubuntu-latest steps: - name: Checkout repository diff --git a/.github/workflows/linux-build.yml b/.github/workflows/linux-build.yml index 5352af623..e92499460 100644 --- a/.github/workflows/linux-build.yml +++ b/.github/workflows/linux-build.yml @@ -39,7 +39,7 @@ jobs: - name: Checkout source code uses: actions/checkout@v4 - name: Replace VERSION - if: inputs.RELEASE == 'testing' || inputs.RELEASE == 'dev' + if: inputs.RELEASE == 'testing' || inputs.RELEASE == 'dev' || inputs.RELEASE == 'ui' run: ./misc/update-version.sh ${{ inputs.RELEASE }} - name: Extract arch run: | @@ -91,7 +91,7 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} # Build testing package image - name: Build package image - if: inputs.RELEASE == 'testing' || inputs.RELEASE == 'dev' + if: inputs.RELEASE == 'testing' || inputs.RELEASE == 'dev' || inputs.RELEASE == 'ui' uses: docker/build-push-action@v5 with: context: . diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index bdf5b1805..0df26a31c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -7,6 +7,16 @@ on: branches: [master] jobs: + scorecards-analysis: + uses: ./.github/workflows/scorecards-analysis.yml + + codeql: + uses: ./.github/workflows/codeql.yml + permissions: + actions: read + contents: read + security-events: write + # Build amd64 + 386 containers images build-containers: strategy: @@ -123,7 +133,7 @@ jobs: # Wait for all builds and extract VERSION wait-builds: runs-on: ubuntu-latest - needs: [build-containers, build-containers-arm, build-packages] + needs: [codeql, build-containers, build-containers-arm, build-packages] outputs: version: ${{ steps.getversion.outputs.version }} versionrpm: ${{ steps.getversionrpm.outputs.versionrpm }} diff --git a/.github/workflows/scorecards-analysis.yml b/.github/workflows/scorecards-analysis.yml new file mode 100644 index 000000000..df2ee1a26 --- /dev/null +++ b/.github/workflows/scorecards-analysis.yml @@ -0,0 +1,30 @@ +name: Scorecard analysis workflow + +on: + branch_protection_rule: + schedule: + # Weekly on Saturdays. + - cron: "30 1 * * 6" + workflow_call: + +permissions: read-all + +jobs: + analysis: + name: Scorecard analysis + runs-on: ubuntu-latest + steps: + - name: "Checkout code" + uses: actions/checkout@v4 + with: + persist-credentials: false + - name: "Run analysis" + uses: ossf/scorecard-action@v2.2.0 + with: + results_file: results.sarif + results_format: sarif + publish_results: true + - name: "Upload SARIF results to code scanning" + uses: github/codeql-action/upload-sarif@v2 + with: + sarif_file: results.sarif diff --git a/.github/workflows/staging.yml b/.github/workflows/staging.yml index a568bda78..7e1762e16 100644 --- a/.github/workflows/staging.yml +++ b/.github/workflows/staging.yml @@ -64,33 +64,16 @@ jobs: DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} DOCKER_TOKEN: ${{ secrets.DOCKER_TOKEN }} - # Python code security - code-security: - runs-on: ubuntu-latest + codeql: + uses: ./.github/workflows/codeql.yml permissions: actions: read contents: read security-events: write - strategy: - fail-fast: false - matrix: - language: ["python"] - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - languages: ${{ matrix.language }} - config-file: ./.github/codeql.yml - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 - with: - category: "/language:${{matrix.language}}" # Create infrastructures and prepare tests create-infras: - needs: [code-security, build-containers, build-packages] + needs: [codeql, build-containers, build-packages] strategy: matrix: type: [docker, autoconf, swarm, k8s, linux] @@ -102,7 +85,7 @@ jobs: SECRET_KEY: ${{ secrets.SECRET_KEY }} K8S_IP: ${{ secrets.K8S_IP }} prepare-tests-core: - needs: [code-security, build-containers, build-packages] + needs: [codeql, build-containers, build-packages] runs-on: ubuntu-latest steps: - name: Checkout repository @@ -116,12 +99,12 @@ jobs: # Perform tests tests-ui: - needs: [code-security, build-containers] + needs: [codeql, build-containers] uses: ./.github/workflows/tests-ui.yml with: RELEASE: testing tests-ui-linux: - needs: [code-security, build-packages] + needs: [codeql, build-packages] uses: ./.github/workflows/tests-ui-linux.yml with: RELEASE: testing diff --git a/.github/workflows/tests-ui-linux.yml b/.github/workflows/tests-ui-linux.yml index 2bbc71ed8..ac6612dea 100644 --- a/.github/workflows/tests-ui-linux.yml +++ b/.github/workflows/tests-ui-linux.yml @@ -62,7 +62,7 @@ jobs: sudo apt update sudo apt install -y nginx=1.24.0-1~jammy - name: Fix version without a starting number - if: inputs.RELEASE == 'testing' || inputs.RELEASE == 'dev' + if: inputs.RELEASE == 'testing' || inputs.RELEASE == 'dev' || inputs.RELEASE == 'ui' run: echo "force-bad-version" | sudo tee -a /etc/dpkg/dpkg.cfg - name: Install BunkerWeb run: sudo apt install -fy /tmp/bunkerweb.deb diff --git a/.github/workflows/ui.yml b/.github/workflows/ui.yml index 5850e6f7b..dd2a33a6f 100644 --- a/.github/workflows/ui.yml +++ b/.github/workflows/ui.yml @@ -33,9 +33,43 @@ jobs: DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} DOCKER_TOKEN: ${{ secrets.DOCKER_TOKEN }} + # Build Linux packages + build-packages: + permissions: + contents: read + packages: write + strategy: + matrix: + linux: [ubuntu] + include: + - linux: ubuntu + package: deb + uses: ./.github/workflows/linux-build.yml + with: + RELEASE: ui + LINUX: ${{ matrix.linux }} + PACKAGE: ${{ matrix.package }} + TEST: true + PLATFORMS: linux/amd64 + secrets: + DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} + DOCKER_TOKEN: ${{ secrets.DOCKER_TOKEN }} + + codeql: + uses: ./.github/workflows/codeql.yml + permissions: + actions: read + contents: read + security-events: write + # UI tests tests-ui: - needs: [build-containers] + needs: [codeql, build-containers] uses: ./.github/workflows/tests-ui.yml with: RELEASE: ui + tests-ui-linux: + needs: [codeql, build-packages] + uses: ./.github/workflows/tests-ui-linux.yml + with: + RELEASE: ui diff --git a/.prettierignore b/.prettierignore index 5450d8b92..743f971fd 100644 --- a/.prettierignore +++ b/.prettierignore @@ -10,5 +10,10 @@ CONTRIBUTING.md LICENSE.md README.md SECURITY.md -src/ui/static -examples/* \ No newline at end of file +tsparticles.bundle.min.js +flatpickr.* +src/ui/static/js/editor/* +src/ui/static/js/utils/purify/* +src/ui/templates/* +datepicker-foundation.css +examples/* diff --git a/README.md b/README.md index 53f2904e4..0d02d3ff5 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,20 @@

- BunkerWeb logo + BunkerWeb logo

+
+
+ + +

@@ -17,7 +22,7 @@ | 👨‍💻 Demo | - 🛡️ Examples + 🛡️ Examples | 💬 Chat | @@ -33,7 +38,7 @@ # BunkerWeb

- overview + Overview banner

BunkerWeb is a next-generation and open-source Web Application Firewall (WAF). @@ -77,7 +82,7 @@ A demo website protected with BunkerWeb is available at [demo.bunkerweb.io](http # Concepts

- BunkerWeb logo + Concepts banner

You will find more information about the key concepts of BunkerWeb in the [documentation](https://docs.bunkerweb.io/1.5.2/concepts). @@ -160,7 +165,7 @@ In other words, the scheduler is the brain of BunkerWeb. ## Docker

- Docker + Docker banner

We provide ready to use prebuilt images for x64, x86, armv7 and arm64 platforms on [Docker Hub](https://hub.docker.com/u/bunkerity). @@ -176,7 +181,7 @@ You will find more information in the [Docker integration section](https://docs. ## Docker autoconf

- Docker autoconf + Docker autoconf banner

The downside of using environment variables is that the container needs to be recreated each time there is an update which is not very convenient. To counter that issue, you can use another image called **autoconf** which will listen for Docker events and automatically reconfigure BunkerWeb in real-time without recreating the container. @@ -188,7 +193,7 @@ You will find more information in the [Docker autoconf section](https://docs.bun ## Swarm

- Swarm + Swarm banner

To automatically configure BunkerWeb instances, a special service, called **autoconf** will listen for Docker Swarm events like service creation or deletion and automatically configure the **BunkerWeb instances** in real-time without downtime. @@ -200,7 +205,7 @@ You will find more information in the [Swarm section](https://docs.bunkerweb.io/ ## Kubernetes

- Kubernetes + Kubernetes banner

The autoconf acts as an [Ingress controller](https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/) and will configure the BunkerWeb instances according to the [Ingress resources](https://kubernetes.io/docs/concepts/services-networking/ingress/). It also monitors other Kubernetes objects like [ConfigMap](https://kubernetes.io/docs/concepts/configuration/configmap/) for custom configurations. @@ -210,7 +215,7 @@ You will find more information in the [Kubernetes section](https://docs.bunkerwe ## Linux

- Linux + Linux banner

List of supported Linux distros : @@ -227,7 +232,7 @@ You will find more information in the [Linux section](https://docs.bunkerweb.io/ ## Ansible

- Ansible + Ansible banner

List of supported Linux distros : @@ -282,7 +287,7 @@ Check the [settings section](https://docs.bunkerweb.io/1.5.2/settings) of the do # Web UI

- BunkerWeb UI demo +

The "Web UI" is a web application that helps you manage your BunkerWeb instance using a user-friendly interface instead of the command-line one. @@ -303,15 +308,15 @@ BunkerWeb comes with a plugin system to make it possible to easily add new featu Here is the list of "official" plugins that we maintain (see the [bunkerweb-plugins](https://github.com/bunkerity/bunkerweb-plugins) repository for more information) : -| Name | Version | Description | Link | -| :------------: | :-----: | :------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------: | +| Name | Version | Description | Link | +| :------------: | :-----: | :------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------: | | **ClamAV** | 1.1 | Automatically scans uploaded files with the ClamAV antivirus engine and denies the request when a file is detected as malicious. | [bunkerweb-plugins/clamav](https://github.com/bunkerity/bunkerweb-plugins/tree/main/clamav) | -| **Coraza** | 1.1 | Inspect requests using a the Coraza WAF (alternative of ModSecurity). | [bunkerweb-plugins/coraza](https://github.com/bunkerity/bunkerweb-plugins/tree/main/coraza) | +| **Coraza** | 1.1 | Inspect requests using a the Coraza WAF (alternative of ModSecurity). | [bunkerweb-plugins/coraza](https://github.com/bunkerity/bunkerweb-plugins/tree/main/coraza) | | **CrowdSec** | 1.1 | CrowdSec bouncer for BunkerWeb. | [bunkerweb-plugins/crowdsec](https://github.com/bunkerity/bunkerweb-plugins/tree/main/crowdsec) | -| **Discord** | 1.1 | Send security notifications to a Discord channel using a Webhook. | [bunkerweb-plugins/discord](https://github.com/bunkerity/bunkerweb-plugins/tree/main/discord) | -| **Slack** | 1.1 | Send security notifications to a Slack channel using a Webhook. | [bunkerweb-plugins/slack](https://github.com/bunkerity/bunkerweb-plugins/tree/main/slack) | +| **Discord** | 1.1 | Send security notifications to a Discord channel using a Webhook. | [bunkerweb-plugins/discord](https://github.com/bunkerity/bunkerweb-plugins/tree/main/discord) | +| **Slack** | 1.1 | Send security notifications to a Slack channel using a Webhook. | [bunkerweb-plugins/slack](https://github.com/bunkerity/bunkerweb-plugins/tree/main/slack) | | **VirusTotal** | 1.1 | Automatically scans uploaded files with the VirusTotal API and denies the request when a file is detected as malicious. | [bunkerweb-plugins/virustotal](https://github.com/bunkerity/bunkerweb-plugins/tree/main/virustotal) | -| **WebHook** | 1.1 | Send security notifications to a custom HTTP endpoint using a Webhook. | [bunkerweb-plugins/slack](https://github.com/bunkerity/bunkerweb-plugins/tree/main/webhook) | +| **WebHook** | 1.1 | Send security notifications to a custom HTTP endpoint using a Webhook. | [bunkerweb-plugins/slack](https://github.com/bunkerity/bunkerweb-plugins/tree/main/webhook) | You will find more information in the [plugins section](https://docs.bunkerweb.io/1.5.2/plugins) of the documentation. @@ -341,12 +346,12 @@ Please don't use [GitHub issues](https://github.com/bunkerity/bunkerweb/issues) # License -This project is licensed under the terms of the [GNU Affero General Public License (AGPL) version 3](https://github.com/bunkerity/bunkerweb/tree/1.5.2/LICENSE.md). +This project is licensed under the terms of the [GNU Affero General Public License (AGPL) version 3](./LICENSE.md). # Contribute -If you would like to contribute to the plugins you can read the [contributing guidelines](https://github.com/bunkerity/bunkerweb/tree/1.5.2/CONTRIBUTING.md) to get started. +If you would like to contribute to the plugins you can read the [contributing guidelines](./CONTRIBUTING.md) to get started. # Security policy -We take security bugs as serious issues and encourage responsible disclosure, see our [security policy](https://github.com/bunkerity/bunkerweb/tree/1.5.2/SECURITY.md) for more information. +We take security bugs as serious issues and encourage responsible disclosure, see our [security policy](./SECURITY.md) for more information. diff --git a/src/ui/static/css/dashboard.css b/src/ui/static/css/dashboard.css index 315b4f010..84fd26557 100644 --- a/src/ui/static/css/dashboard.css +++ b/src/ui/static/css/dashboard.css @@ -2590,15 +2590,34 @@ h6 { } .transition { - transition-property: color, background-color, border-color, - text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, + transition-property: + color, + background-color, + border-color, + text-decoration-color, + fill, + stroke, + opacity, + box-shadow, + transform, + filter, -webkit-backdrop-filter; transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; - transition-property: color, background-color, border-color, - text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, - backdrop-filter, -webkit-backdrop-filter; + transition-property: + color, + background-color, + border-color, + text-decoration-color, + fill, + stroke, + opacity, + box-shadow, + transform, + filter, + backdrop-filter, + -webkit-backdrop-filter; transition-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1); transition-duration: 150ms; } @@ -3310,15 +3329,34 @@ h6 { font-size: 0.875rem; line-height: 1.5rem; font-weight: 700; - transition-property: color, background-color, border-color, - text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, + transition-property: + color, + background-color, + border-color, + text-decoration-color, + fill, + stroke, + opacity, + box-shadow, + transform, + filter, -webkit-backdrop-filter; transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; - transition-property: color, background-color, border-color, - text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, - backdrop-filter, -webkit-backdrop-filter; + transition-property: + color, + background-color, + border-color, + text-decoration-color, + fill, + stroke, + opacity, + box-shadow, + transform, + filter, + backdrop-filter, + -webkit-backdrop-filter; transition-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1); transition-duration: 300ms; transition-timing-function: cubic-bezier(0.42, 0, 0.58, 1); @@ -3343,15 +3381,34 @@ h6 { --tw-bg-opacity: 1; background-color: rgb(94 114 228 / var(--tw-bg-opacity)); padding: 0.75rem; - transition-property: color, background-color, border-color, - text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, + transition-property: + color, + background-color, + border-color, + text-decoration-color, + fill, + stroke, + opacity, + box-shadow, + transform, + filter, -webkit-backdrop-filter; transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; - transition-property: color, background-color, border-color, - text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, - backdrop-filter, -webkit-backdrop-filter; + transition-property: + color, + background-color, + border-color, + text-decoration-color, + fill, + stroke, + opacity, + box-shadow, + transform, + filter, + backdrop-filter, + -webkit-backdrop-filter; transition-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1); transition-duration: 150ms; } @@ -3370,15 +3427,34 @@ h6 { font-weight: 700; --tw-text-opacity: 1; color: rgb(255 255 255 / var(--tw-text-opacity)); - transition-property: color, background-color, border-color, - text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, + transition-property: + color, + background-color, + border-color, + text-decoration-color, + fill, + stroke, + opacity, + box-shadow, + transform, + filter, -webkit-backdrop-filter; transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; - transition-property: color, background-color, border-color, - text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, - backdrop-filter, -webkit-backdrop-filter; + transition-property: + color, + background-color, + border-color, + text-decoration-color, + fill, + stroke, + opacity, + box-shadow, + transform, + filter, + backdrop-filter, + -webkit-backdrop-filter; transition-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1); transition-duration: 300ms; transition-timing-function: cubic-bezier(0.42, 0, 0.58, 1); @@ -3539,15 +3615,34 @@ h6 { padding-right: 0.5rem; --tw-text-opacity: 1; color: rgb(8 85 119 / var(--tw-text-opacity)); - transition-property: color, background-color, border-color, - text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, + transition-property: + color, + background-color, + border-color, + text-decoration-color, + fill, + stroke, + opacity, + box-shadow, + transform, + filter, -webkit-backdrop-filter; transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; - transition-property: color, background-color, border-color, - text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, - backdrop-filter, -webkit-backdrop-filter; + transition-property: + color, + background-color, + border-color, + text-decoration-color, + fill, + stroke, + opacity, + box-shadow, + transform, + filter, + backdrop-filter, + -webkit-backdrop-filter; transition-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1); transition-duration: 300ms; transition-timing-function: cubic-bezier(0.42, 0, 0.58, 1); @@ -3569,15 +3664,34 @@ h6 { --tw-bg-opacity: 1; background-color: rgb(94 114 228 / var(--tw-bg-opacity)); padding: 0.75rem; - transition-property: color, background-color, border-color, - text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, + transition-property: + color, + background-color, + border-color, + text-decoration-color, + fill, + stroke, + opacity, + box-shadow, + transform, + filter, -webkit-backdrop-filter; transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; - transition-property: color, background-color, border-color, - text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, - backdrop-filter, -webkit-backdrop-filter; + transition-property: + color, + background-color, + border-color, + text-decoration-color, + fill, + stroke, + opacity, + box-shadow, + transform, + filter, + backdrop-filter, + -webkit-backdrop-filter; transition-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1); transition-duration: 150ms; } @@ -3666,15 +3780,34 @@ h6 { .settings-tabs-mobile-btn-text { --tw-text-opacity: 1; color: rgb(8 85 119 / var(--tw-text-opacity)); - transition-property: color, background-color, border-color, - text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, + transition-property: + color, + background-color, + border-color, + text-decoration-color, + fill, + stroke, + opacity, + box-shadow, + transform, + filter, -webkit-backdrop-filter; transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; - transition-property: color, background-color, border-color, - text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, - backdrop-filter, -webkit-backdrop-filter; + transition-property: + color, + background-color, + border-color, + text-decoration-color, + fill, + stroke, + opacity, + box-shadow, + transform, + filter, + backdrop-filter, + -webkit-backdrop-filter; transition-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1); transition-duration: 300ms; transition-timing-function: cubic-bezier(0.42, 0, 0.58, 1); diff --git a/src/ui/static/css/datepicker-foundation.min.css b/src/ui/static/css/datepicker-foundation.min.css deleted file mode 100644 index 8465be876..000000000 --- a/src/ui/static/css/datepicker-foundation.min.css +++ /dev/null @@ -1 +0,0 @@ -.datepicker{display:none}.datepicker.active{display:block}.datepicker-dropdown{left:0;padding-top:4px;position:absolute;top:0;z-index:10}.datepicker-dropdown.datepicker-orient-top{padding-bottom:4px;padding-top:0}.datepicker-picker{background-color:#fefefe;border-radius:0;display:inline-block}.datepicker-dropdown .datepicker-picker{box-shadow:0 0 0 1px #cacaca}.datepicker-picker span{-webkit-touch-callout:none;border:0;border-radius:0;cursor:default;display:block;flex:1;text-align:center;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.datepicker-main{padding:2px}.datepicker-footer{background-color:#e6e6e6;box-shadow:inset 0 1px 1px hsla(0,0%,4%,.1)}.datepicker-controls,.datepicker-grid,.datepicker-view,.datepicker-view .days-of-week{display:flex}.datepicker-grid{flex-wrap:wrap}.datepicker-view .days .datepicker-cell,.datepicker-view .dow{flex-basis:14.2857142857%}.datepicker-view.datepicker-grid .datepicker-cell{flex-basis:25%}.datepicker-cell,.datepicker-view .week{height:2.25rem;line-height:2.25rem}.datepicker-title{background-color:#e6e6e6;box-shadow:inset 0 -1px 1px hsla(0,0%,4%,.1);font-weight:700;padding:.375rem .75rem;text-align:center}.datepicker-header .datepicker-controls{padding:2px 2px 0}.datepicker-controls .button{background-color:#fefefe;color:#0a0a0a;margin:0}.datepicker-controls .button:focus,.datepicker-controls .button:hover{background-color:#d8d8d8}.datepicker-controls .button:focus[disabled],.datepicker-controls .button:hover[disabled]{background-color:#fefefe;color:#0a0a0a;opacity:.25}.datepicker-header .datepicker-controls .button{border-color:transparent;font-weight:700}.datepicker-footer .datepicker-controls .button{border-radius:0;font-size:.75rem;margin:calc(.375rem - 1px) .375rem;width:100%}.datepicker-controls .view-switch{flex:auto}.datepicker-controls .next-btn,.datepicker-controls .prev-btn{padding-left:.375rem;padding-right:.375rem;width:2.25rem}.datepicker-controls .next-btn.disabled,.datepicker-controls .prev-btn.disabled{visibility:hidden}.datepicker-view .dow{font-size:.875rem;font-weight:700;height:1.5rem;line-height:1.5rem}.datepicker-view .week{color:#8a8a8a;font-size:.75rem;width:2.25rem}@media (max-width:22.5rem){.datepicker-view .week{width:1.96875rem}}.datepicker-grid{width:15.75rem}@media (max-width:22.5rem){.calendar-weeks+.days .datepicker-grid{width:13.78125rem}}.datepicker-cell:not(.disabled):hover{background-color:#f8f8f8;cursor:pointer}.datepicker-cell.focused:not(.selected){background-color:#f1f1f1}.datepicker-cell.selected,.datepicker-cell.selected:hover{background-color:#1779ba;color:#fefefe;font-weight:semibold}.datepicker-cell.disabled{color:#e6e6e6}.datepicker-cell.next:not(.disabled),.datepicker-cell.prev:not(.disabled){color:#cacaca}.datepicker-cell.next.selected,.datepicker-cell.prev.selected{color:#e5e5e5}.datepicker-cell.highlighted:not(.selected):not(.range):not(.today){background-color:#f7f7f7;border-radius:0}.datepicker-cell.highlighted:not(.selected):not(.range):not(.today).focused,.datepicker-cell.highlighted:not(.selected):not(.range):not(.today):not(.disabled):hover{background-color:#f1f1f1}.datepicker-cell.today:not(.selected){background-color:#d7ecfa}.datepicker-cell.today:not(.selected):not(.disabled){color:#8a8a8a}.datepicker-cell.today.focused:not(.selected){background-color:#cbe7f9}.datepicker-cell.range-end:not(.selected),.datepicker-cell.range-start:not(.selected){background-color:#767676;color:#fefefe}.datepicker-cell.range-end.focused:not(.selected),.datepicker-cell.range-start.focused:not(.selected){background-color:#707070}.datepicker-cell.range-end,.datepicker-cell.range-start{border-radius:0 0 0 0}.datepicker-cell.range{background-color:#e6e6e6;border-radius:0}.datepicker-cell.range:not(.disabled):not(.focused):not(.today):hover{background-color:#e0e0e0}.datepicker-cell.range.disabled{color:#cdcdcd}.datepicker-cell.range.focused{background-color:#d9d9d9}.datepicker-cell.range.today{background-color:#b3dbf6}.datepicker-view.datepicker-grid .datepicker-cell{height:4.5rem;line-height:4.5rem}.datepicker-input.in-edit{border-color:#a4a4a4}.datepicker-input.in-edit:active,.datepicker-input.in-edit:focus{box-shadow:0 0 .25em .25em hsla(0,0%,64%,.2)} \ No newline at end of file diff --git a/src/ui/static/js/939.js b/src/ui/static/js/939.js deleted file mode 100644 index e6f35f230..000000000 --- a/src/ui/static/js/939.js +++ /dev/null @@ -1,1780 +0,0 @@ -/*! - * Author : Matteo Bruni - * MIT license: https://opensource.org/licenses/MIT - * Demo / Generator : https://particles.js.org/ - * GitHub : https://www.github.com/matteobruni/tsparticles - * How to use? : Check the GitHub README - * v2.0.6 - */ -"use strict"; -(this["webpackChunktsparticles"] = this["webpackChunktsparticles"] || []).push([[939],{ - -/***/ 939: -/***/ (() => { - - - -(function () { - "use strict"; - - try { - if (typeof window === "undefined") return; - - if (!("SVGPathSeg" in window)) { - window.SVGPathSeg = function (type, typeAsLetter, owningPathSegList) { - this.pathSegType = type; - this.pathSegTypeAsLetter = typeAsLetter; - this._owningPathSegList = owningPathSegList; - }; - - window.SVGPathSeg.prototype.classname = "SVGPathSeg"; - window.SVGPathSeg.PATHSEG_UNKNOWN = 0; - window.SVGPathSeg.PATHSEG_CLOSEPATH = 1; - window.SVGPathSeg.PATHSEG_MOVETO_ABS = 2; - window.SVGPathSeg.PATHSEG_MOVETO_REL = 3; - window.SVGPathSeg.PATHSEG_LINETO_ABS = 4; - window.SVGPathSeg.PATHSEG_LINETO_REL = 5; - window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS = 6; - window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL = 7; - window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS = 8; - window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL = 9; - window.SVGPathSeg.PATHSEG_ARC_ABS = 10; - window.SVGPathSeg.PATHSEG_ARC_REL = 11; - window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS = 12; - window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL = 13; - window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS = 14; - window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL = 15; - window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS = 16; - window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL = 17; - window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS = 18; - window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL = 19; - - window.SVGPathSeg.prototype._segmentChanged = function () { - if (this._owningPathSegList) this._owningPathSegList.segmentChanged(this); - }; - - window.SVGPathSegClosePath = function (owningPathSegList) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CLOSEPATH, "z", owningPathSegList); - }; - - window.SVGPathSegClosePath.prototype = Object.create(window.SVGPathSeg.prototype); - - window.SVGPathSegClosePath.prototype.toString = function () { - return "[object SVGPathSegClosePath]"; - }; - - window.SVGPathSegClosePath.prototype._asPathString = function () { - return this.pathSegTypeAsLetter; - }; - - window.SVGPathSegClosePath.prototype.clone = function () { - return new window.SVGPathSegClosePath(undefined); - }; - - window.SVGPathSegMovetoAbs = function (owningPathSegList, x, y) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_MOVETO_ABS, "M", owningPathSegList); - this._x = x; - this._y = y; - }; - - window.SVGPathSegMovetoAbs.prototype = Object.create(window.SVGPathSeg.prototype); - - window.SVGPathSegMovetoAbs.prototype.toString = function () { - return "[object SVGPathSegMovetoAbs]"; - }; - - window.SVGPathSegMovetoAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; - }; - - window.SVGPathSegMovetoAbs.prototype.clone = function () { - return new window.SVGPathSegMovetoAbs(undefined, this._x, this._y); - }; - - Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - - this._segmentChanged(); - }, - enumerable: true - }); - - window.SVGPathSegMovetoRel = function (owningPathSegList, x, y) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_MOVETO_REL, "m", owningPathSegList); - this._x = x; - this._y = y; - }; - - window.SVGPathSegMovetoRel.prototype = Object.create(window.SVGPathSeg.prototype); - - window.SVGPathSegMovetoRel.prototype.toString = function () { - return "[object SVGPathSegMovetoRel]"; - }; - - window.SVGPathSegMovetoRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; - }; - - window.SVGPathSegMovetoRel.prototype.clone = function () { - return new window.SVGPathSegMovetoRel(undefined, this._x, this._y); - }; - - Object.defineProperty(window.SVGPathSegMovetoRel.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegMovetoRel.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - - this._segmentChanged(); - }, - enumerable: true - }); - - window.SVGPathSegLinetoAbs = function (owningPathSegList, x, y) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_ABS, "L", owningPathSegList); - this._x = x; - this._y = y; - }; - - window.SVGPathSegLinetoAbs.prototype = Object.create(window.SVGPathSeg.prototype); - - window.SVGPathSegLinetoAbs.prototype.toString = function () { - return "[object SVGPathSegLinetoAbs]"; - }; - - window.SVGPathSegLinetoAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; - }; - - window.SVGPathSegLinetoAbs.prototype.clone = function () { - return new window.SVGPathSegLinetoAbs(undefined, this._x, this._y); - }; - - Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - - this._segmentChanged(); - }, - enumerable: true - }); - - window.SVGPathSegLinetoRel = function (owningPathSegList, x, y) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_REL, "l", owningPathSegList); - this._x = x; - this._y = y; - }; - - window.SVGPathSegLinetoRel.prototype = Object.create(window.SVGPathSeg.prototype); - - window.SVGPathSegLinetoRel.prototype.toString = function () { - return "[object SVGPathSegLinetoRel]"; - }; - - window.SVGPathSegLinetoRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; - }; - - window.SVGPathSegLinetoRel.prototype.clone = function () { - return new window.SVGPathSegLinetoRel(undefined, this._x, this._y); - }; - - Object.defineProperty(window.SVGPathSegLinetoRel.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegLinetoRel.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - - this._segmentChanged(); - }, - enumerable: true - }); - - window.SVGPathSegCurvetoCubicAbs = function (owningPathSegList, x, y, x1, y1, x2, y2) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS, "C", owningPathSegList); - this._x = x; - this._y = y; - this._x1 = x1; - this._y1 = y1; - this._x2 = x2; - this._y2 = y2; - }; - - window.SVGPathSegCurvetoCubicAbs.prototype = Object.create(window.SVGPathSeg.prototype); - - window.SVGPathSegCurvetoCubicAbs.prototype.toString = function () { - return "[object SVGPathSegCurvetoCubicAbs]"; - }; - - window.SVGPathSegCurvetoCubicAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y; - }; - - window.SVGPathSegCurvetoCubicAbs.prototype.clone = function () { - return new window.SVGPathSegCurvetoCubicAbs(undefined, this._x, this._y, this._x1, this._y1, this._x2, this._y2); - }; - - Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "x1", { - get: function () { - return this._x1; - }, - set: function (x1) { - this._x1 = x1; - - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "y1", { - get: function () { - return this._y1; - }, - set: function (y1) { - this._y1 = y1; - - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "x2", { - get: function () { - return this._x2; - }, - set: function (x2) { - this._x2 = x2; - - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "y2", { - get: function () { - return this._y2; - }, - set: function (y2) { - this._y2 = y2; - - this._segmentChanged(); - }, - enumerable: true - }); - - window.SVGPathSegCurvetoCubicRel = function (owningPathSegList, x, y, x1, y1, x2, y2) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL, "c", owningPathSegList); - this._x = x; - this._y = y; - this._x1 = x1; - this._y1 = y1; - this._x2 = x2; - this._y2 = y2; - }; - - window.SVGPathSegCurvetoCubicRel.prototype = Object.create(window.SVGPathSeg.prototype); - - window.SVGPathSegCurvetoCubicRel.prototype.toString = function () { - return "[object SVGPathSegCurvetoCubicRel]"; - }; - - window.SVGPathSegCurvetoCubicRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y; - }; - - window.SVGPathSegCurvetoCubicRel.prototype.clone = function () { - return new window.SVGPathSegCurvetoCubicRel(undefined, this._x, this._y, this._x1, this._y1, this._x2, this._y2); - }; - - Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "x1", { - get: function () { - return this._x1; - }, - set: function (x1) { - this._x1 = x1; - - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "y1", { - get: function () { - return this._y1; - }, - set: function (y1) { - this._y1 = y1; - - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "x2", { - get: function () { - return this._x2; - }, - set: function (x2) { - this._x2 = x2; - - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "y2", { - get: function () { - return this._y2; - }, - set: function (y2) { - this._y2 = y2; - - this._segmentChanged(); - }, - enumerable: true - }); - - window.SVGPathSegCurvetoQuadraticAbs = function (owningPathSegList, x, y, x1, y1) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS, "Q", owningPathSegList); - this._x = x; - this._y = y; - this._x1 = x1; - this._y1 = y1; - }; - - window.SVGPathSegCurvetoQuadraticAbs.prototype = Object.create(window.SVGPathSeg.prototype); - - window.SVGPathSegCurvetoQuadraticAbs.prototype.toString = function () { - return "[object SVGPathSegCurvetoQuadraticAbs]"; - }; - - window.SVGPathSegCurvetoQuadraticAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x + " " + this._y; - }; - - window.SVGPathSegCurvetoQuadraticAbs.prototype.clone = function () { - return new window.SVGPathSegCurvetoQuadraticAbs(undefined, this._x, this._y, this._x1, this._y1); - }; - - Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "x1", { - get: function () { - return this._x1; - }, - set: function (x1) { - this._x1 = x1; - - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "y1", { - get: function () { - return this._y1; - }, - set: function (y1) { - this._y1 = y1; - - this._segmentChanged(); - }, - enumerable: true - }); - - window.SVGPathSegCurvetoQuadraticRel = function (owningPathSegList, x, y, x1, y1) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL, "q", owningPathSegList); - this._x = x; - this._y = y; - this._x1 = x1; - this._y1 = y1; - }; - - window.SVGPathSegCurvetoQuadraticRel.prototype = Object.create(window.SVGPathSeg.prototype); - - window.SVGPathSegCurvetoQuadraticRel.prototype.toString = function () { - return "[object SVGPathSegCurvetoQuadraticRel]"; - }; - - window.SVGPathSegCurvetoQuadraticRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x + " " + this._y; - }; - - window.SVGPathSegCurvetoQuadraticRel.prototype.clone = function () { - return new window.SVGPathSegCurvetoQuadraticRel(undefined, this._x, this._y, this._x1, this._y1); - }; - - Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "x1", { - get: function () { - return this._x1; - }, - set: function (x1) { - this._x1 = x1; - - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "y1", { - get: function () { - return this._y1; - }, - set: function (y1) { - this._y1 = y1; - - this._segmentChanged(); - }, - enumerable: true - }); - - window.SVGPathSegArcAbs = function (owningPathSegList, x, y, r1, r2, angle, largeArcFlag, sweepFlag) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_ARC_ABS, "A", owningPathSegList); - this._x = x; - this._y = y; - this._r1 = r1; - this._r2 = r2; - this._angle = angle; - this._largeArcFlag = largeArcFlag; - this._sweepFlag = sweepFlag; - }; - - window.SVGPathSegArcAbs.prototype = Object.create(window.SVGPathSeg.prototype); - - window.SVGPathSegArcAbs.prototype.toString = function () { - return "[object SVGPathSegArcAbs]"; - }; - - window.SVGPathSegArcAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._r1 + " " + this._r2 + " " + this._angle + " " + (this._largeArcFlag ? "1" : "0") + " " + (this._sweepFlag ? "1" : "0") + " " + this._x + " " + this._y; - }; - - window.SVGPathSegArcAbs.prototype.clone = function () { - return new window.SVGPathSegArcAbs(undefined, this._x, this._y, this._r1, this._r2, this._angle, this._largeArcFlag, this._sweepFlag); - }; - - Object.defineProperty(window.SVGPathSegArcAbs.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegArcAbs.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegArcAbs.prototype, "r1", { - get: function () { - return this._r1; - }, - set: function (r1) { - this._r1 = r1; - - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegArcAbs.prototype, "r2", { - get: function () { - return this._r2; - }, - set: function (r2) { - this._r2 = r2; - - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegArcAbs.prototype, "angle", { - get: function () { - return this._angle; - }, - set: function (angle) { - this._angle = angle; - - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegArcAbs.prototype, "largeArcFlag", { - get: function () { - return this._largeArcFlag; - }, - set: function (largeArcFlag) { - this._largeArcFlag = largeArcFlag; - - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegArcAbs.prototype, "sweepFlag", { - get: function () { - return this._sweepFlag; - }, - set: function (sweepFlag) { - this._sweepFlag = sweepFlag; - - this._segmentChanged(); - }, - enumerable: true - }); - - window.SVGPathSegArcRel = function (owningPathSegList, x, y, r1, r2, angle, largeArcFlag, sweepFlag) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_ARC_REL, "a", owningPathSegList); - this._x = x; - this._y = y; - this._r1 = r1; - this._r2 = r2; - this._angle = angle; - this._largeArcFlag = largeArcFlag; - this._sweepFlag = sweepFlag; - }; - - window.SVGPathSegArcRel.prototype = Object.create(window.SVGPathSeg.prototype); - - window.SVGPathSegArcRel.prototype.toString = function () { - return "[object SVGPathSegArcRel]"; - }; - - window.SVGPathSegArcRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._r1 + " " + this._r2 + " " + this._angle + " " + (this._largeArcFlag ? "1" : "0") + " " + (this._sweepFlag ? "1" : "0") + " " + this._x + " " + this._y; - }; - - window.SVGPathSegArcRel.prototype.clone = function () { - return new window.SVGPathSegArcRel(undefined, this._x, this._y, this._r1, this._r2, this._angle, this._largeArcFlag, this._sweepFlag); - }; - - Object.defineProperty(window.SVGPathSegArcRel.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegArcRel.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegArcRel.prototype, "r1", { - get: function () { - return this._r1; - }, - set: function (r1) { - this._r1 = r1; - - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegArcRel.prototype, "r2", { - get: function () { - return this._r2; - }, - set: function (r2) { - this._r2 = r2; - - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegArcRel.prototype, "angle", { - get: function () { - return this._angle; - }, - set: function (angle) { - this._angle = angle; - - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegArcRel.prototype, "largeArcFlag", { - get: function () { - return this._largeArcFlag; - }, - set: function (largeArcFlag) { - this._largeArcFlag = largeArcFlag; - - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegArcRel.prototype, "sweepFlag", { - get: function () { - return this._sweepFlag; - }, - set: function (sweepFlag) { - this._sweepFlag = sweepFlag; - - this._segmentChanged(); - }, - enumerable: true - }); - - window.SVGPathSegLinetoHorizontalAbs = function (owningPathSegList, x) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS, "H", owningPathSegList); - this._x = x; - }; - - window.SVGPathSegLinetoHorizontalAbs.prototype = Object.create(window.SVGPathSeg.prototype); - - window.SVGPathSegLinetoHorizontalAbs.prototype.toString = function () { - return "[object SVGPathSegLinetoHorizontalAbs]"; - }; - - window.SVGPathSegLinetoHorizontalAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x; - }; - - window.SVGPathSegLinetoHorizontalAbs.prototype.clone = function () { - return new window.SVGPathSegLinetoHorizontalAbs(undefined, this._x); - }; - - Object.defineProperty(window.SVGPathSegLinetoHorizontalAbs.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - - this._segmentChanged(); - }, - enumerable: true - }); - - window.SVGPathSegLinetoHorizontalRel = function (owningPathSegList, x) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL, "h", owningPathSegList); - this._x = x; - }; - - window.SVGPathSegLinetoHorizontalRel.prototype = Object.create(window.SVGPathSeg.prototype); - - window.SVGPathSegLinetoHorizontalRel.prototype.toString = function () { - return "[object SVGPathSegLinetoHorizontalRel]"; - }; - - window.SVGPathSegLinetoHorizontalRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x; - }; - - window.SVGPathSegLinetoHorizontalRel.prototype.clone = function () { - return new window.SVGPathSegLinetoHorizontalRel(undefined, this._x); - }; - - Object.defineProperty(window.SVGPathSegLinetoHorizontalRel.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - - this._segmentChanged(); - }, - enumerable: true - }); - - window.SVGPathSegLinetoVerticalAbs = function (owningPathSegList, y) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS, "V", owningPathSegList); - this._y = y; - }; - - window.SVGPathSegLinetoVerticalAbs.prototype = Object.create(window.SVGPathSeg.prototype); - - window.SVGPathSegLinetoVerticalAbs.prototype.toString = function () { - return "[object SVGPathSegLinetoVerticalAbs]"; - }; - - window.SVGPathSegLinetoVerticalAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._y; - }; - - window.SVGPathSegLinetoVerticalAbs.prototype.clone = function () { - return new window.SVGPathSegLinetoVerticalAbs(undefined, this._y); - }; - - Object.defineProperty(window.SVGPathSegLinetoVerticalAbs.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - - this._segmentChanged(); - }, - enumerable: true - }); - - window.SVGPathSegLinetoVerticalRel = function (owningPathSegList, y) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL, "v", owningPathSegList); - this._y = y; - }; - - window.SVGPathSegLinetoVerticalRel.prototype = Object.create(window.SVGPathSeg.prototype); - - window.SVGPathSegLinetoVerticalRel.prototype.toString = function () { - return "[object SVGPathSegLinetoVerticalRel]"; - }; - - window.SVGPathSegLinetoVerticalRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._y; - }; - - window.SVGPathSegLinetoVerticalRel.prototype.clone = function () { - return new window.SVGPathSegLinetoVerticalRel(undefined, this._y); - }; - - Object.defineProperty(window.SVGPathSegLinetoVerticalRel.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - - this._segmentChanged(); - }, - enumerable: true - }); - - window.SVGPathSegCurvetoCubicSmoothAbs = function (owningPathSegList, x, y, x2, y2) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS, "S", owningPathSegList); - this._x = x; - this._y = y; - this._x2 = x2; - this._y2 = y2; - }; - - window.SVGPathSegCurvetoCubicSmoothAbs.prototype = Object.create(window.SVGPathSeg.prototype); - - window.SVGPathSegCurvetoCubicSmoothAbs.prototype.toString = function () { - return "[object SVGPathSegCurvetoCubicSmoothAbs]"; - }; - - window.SVGPathSegCurvetoCubicSmoothAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y; - }; - - window.SVGPathSegCurvetoCubicSmoothAbs.prototype.clone = function () { - return new window.SVGPathSegCurvetoCubicSmoothAbs(undefined, this._x, this._y, this._x2, this._y2); - }; - - Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "x2", { - get: function () { - return this._x2; - }, - set: function (x2) { - this._x2 = x2; - - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "y2", { - get: function () { - return this._y2; - }, - set: function (y2) { - this._y2 = y2; - - this._segmentChanged(); - }, - enumerable: true - }); - - window.SVGPathSegCurvetoCubicSmoothRel = function (owningPathSegList, x, y, x2, y2) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL, "s", owningPathSegList); - this._x = x; - this._y = y; - this._x2 = x2; - this._y2 = y2; - }; - - window.SVGPathSegCurvetoCubicSmoothRel.prototype = Object.create(window.SVGPathSeg.prototype); - - window.SVGPathSegCurvetoCubicSmoothRel.prototype.toString = function () { - return "[object SVGPathSegCurvetoCubicSmoothRel]"; - }; - - window.SVGPathSegCurvetoCubicSmoothRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y; - }; - - window.SVGPathSegCurvetoCubicSmoothRel.prototype.clone = function () { - return new window.SVGPathSegCurvetoCubicSmoothRel(undefined, this._x, this._y, this._x2, this._y2); - }; - - Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "x2", { - get: function () { - return this._x2; - }, - set: function (x2) { - this._x2 = x2; - - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "y2", { - get: function () { - return this._y2; - }, - set: function (y2) { - this._y2 = y2; - - this._segmentChanged(); - }, - enumerable: true - }); - - window.SVGPathSegCurvetoQuadraticSmoothAbs = function (owningPathSegList, x, y) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS, "T", owningPathSegList); - this._x = x; - this._y = y; - }; - - window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype = Object.create(window.SVGPathSeg.prototype); - - window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.toString = function () { - return "[object SVGPathSegCurvetoQuadraticSmoothAbs]"; - }; - - window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; - }; - - window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.clone = function () { - return new window.SVGPathSegCurvetoQuadraticSmoothAbs(undefined, this._x, this._y); - }; - - Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - - this._segmentChanged(); - }, - enumerable: true - }); - - window.SVGPathSegCurvetoQuadraticSmoothRel = function (owningPathSegList, x, y) { - window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL, "t", owningPathSegList); - this._x = x; - this._y = y; - }; - - window.SVGPathSegCurvetoQuadraticSmoothRel.prototype = Object.create(window.SVGPathSeg.prototype); - - window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.toString = function () { - return "[object SVGPathSegCurvetoQuadraticSmoothRel]"; - }; - - window.SVGPathSegCurvetoQuadraticSmoothRel.prototype._asPathString = function () { - return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; - }; - - window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.clone = function () { - return new window.SVGPathSegCurvetoQuadraticSmoothRel(undefined, this._x, this._y); - }; - - Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, "x", { - get: function () { - return this._x; - }, - set: function (x) { - this._x = x; - - this._segmentChanged(); - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, "y", { - get: function () { - return this._y; - }, - set: function (y) { - this._y = y; - - this._segmentChanged(); - }, - enumerable: true - }); - - window.SVGPathElement.prototype.createSVGPathSegClosePath = function () { - return new window.SVGPathSegClosePath(undefined); - }; - - window.SVGPathElement.prototype.createSVGPathSegMovetoAbs = function (x, y) { - return new window.SVGPathSegMovetoAbs(undefined, x, y); - }; - - window.SVGPathElement.prototype.createSVGPathSegMovetoRel = function (x, y) { - return new window.SVGPathSegMovetoRel(undefined, x, y); - }; - - window.SVGPathElement.prototype.createSVGPathSegLinetoAbs = function (x, y) { - return new window.SVGPathSegLinetoAbs(undefined, x, y); - }; - - window.SVGPathElement.prototype.createSVGPathSegLinetoRel = function (x, y) { - return new window.SVGPathSegLinetoRel(undefined, x, y); - }; - - window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicAbs = function (x, y, x1, y1, x2, y2) { - return new window.SVGPathSegCurvetoCubicAbs(undefined, x, y, x1, y1, x2, y2); - }; - - window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicRel = function (x, y, x1, y1, x2, y2) { - return new window.SVGPathSegCurvetoCubicRel(undefined, x, y, x1, y1, x2, y2); - }; - - window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticAbs = function (x, y, x1, y1) { - return new window.SVGPathSegCurvetoQuadraticAbs(undefined, x, y, x1, y1); - }; - - window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticRel = function (x, y, x1, y1) { - return new window.SVGPathSegCurvetoQuadraticRel(undefined, x, y, x1, y1); - }; - - window.SVGPathElement.prototype.createSVGPathSegArcAbs = function (x, y, r1, r2, angle, largeArcFlag, sweepFlag) { - return new window.SVGPathSegArcAbs(undefined, x, y, r1, r2, angle, largeArcFlag, sweepFlag); - }; - - window.SVGPathElement.prototype.createSVGPathSegArcRel = function (x, y, r1, r2, angle, largeArcFlag, sweepFlag) { - return new window.SVGPathSegArcRel(undefined, x, y, r1, r2, angle, largeArcFlag, sweepFlag); - }; - - window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalAbs = function (x) { - return new window.SVGPathSegLinetoHorizontalAbs(undefined, x); - }; - - window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalRel = function (x) { - return new window.SVGPathSegLinetoHorizontalRel(undefined, x); - }; - - window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalAbs = function (y) { - return new window.SVGPathSegLinetoVerticalAbs(undefined, y); - }; - - window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalRel = function (y) { - return new window.SVGPathSegLinetoVerticalRel(undefined, y); - }; - - window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothAbs = function (x, y, x2, y2) { - return new window.SVGPathSegCurvetoCubicSmoothAbs(undefined, x, y, x2, y2); - }; - - window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothRel = function (x, y, x2, y2) { - return new window.SVGPathSegCurvetoCubicSmoothRel(undefined, x, y, x2, y2); - }; - - window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothAbs = function (x, y) { - return new window.SVGPathSegCurvetoQuadraticSmoothAbs(undefined, x, y); - }; - - window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothRel = function (x, y) { - return new window.SVGPathSegCurvetoQuadraticSmoothRel(undefined, x, y); - }; - - if (!("getPathSegAtLength" in window.SVGPathElement.prototype)) { - window.SVGPathElement.prototype.getPathSegAtLength = function (distance) { - if (distance === undefined || !isFinite(distance)) throw "Invalid arguments."; - const measurementElement = document.createElementNS("http://www.w3.org/2000/svg", "path"); - measurementElement.setAttribute("d", this.getAttribute("d")); - let lastPathSegment = measurementElement.pathSegList.numberOfItems - 1; - if (lastPathSegment <= 0) return 0; - - do { - measurementElement.pathSegList.removeItem(lastPathSegment); - if (distance > measurementElement.getTotalLength()) break; - lastPathSegment--; - } while (lastPathSegment > 0); - - return lastPathSegment; - }; - } - } - - if (!("SVGPathSegList" in window) || !("appendItem" in window.SVGPathSegList.prototype)) { - window.SVGPathSegList = function (pathElement) { - this._pathElement = pathElement; - this._list = this._parsePath(this._pathElement.getAttribute("d")); - this._mutationObserverConfig = { - attributes: true, - attributeFilter: ["d"] - }; - this._pathElementMutationObserver = new MutationObserver(this._updateListFromPathMutations.bind(this)); - - this._pathElementMutationObserver.observe(this._pathElement, this._mutationObserverConfig); - }; - - window.SVGPathSegList.prototype.classname = "SVGPathSegList"; - Object.defineProperty(window.SVGPathSegList.prototype, "numberOfItems", { - get: function () { - this._checkPathSynchronizedToList(); - - return this._list.length; - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathSegList.prototype, "length", { - get: function () { - this._checkPathSynchronizedToList(); - - return this._list.length; - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathElement.prototype, "pathSegList", { - get: function () { - if (!this._pathSegList) this._pathSegList = new window.SVGPathSegList(this); - return this._pathSegList; - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathElement.prototype, "normalizedPathSegList", { - get: function () { - return this.pathSegList; - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathElement.prototype, "animatedPathSegList", { - get: function () { - return this.pathSegList; - }, - enumerable: true - }); - Object.defineProperty(window.SVGPathElement.prototype, "animatedNormalizedPathSegList", { - get: function () { - return this.pathSegList; - }, - enumerable: true - }); - - window.SVGPathSegList.prototype._checkPathSynchronizedToList = function () { - this._updateListFromPathMutations(this._pathElementMutationObserver.takeRecords()); - }; - - window.SVGPathSegList.prototype._updateListFromPathMutations = function (mutationRecords) { - if (!this._pathElement) return; - let hasPathMutations = false; - mutationRecords.forEach(function (record) { - if (record.attributeName == "d") hasPathMutations = true; - }); - if (hasPathMutations) this._list = this._parsePath(this._pathElement.getAttribute("d")); - }; - - window.SVGPathSegList.prototype._writeListToPath = function () { - this._pathElementMutationObserver.disconnect(); - - this._pathElement.setAttribute("d", window.SVGPathSegList._pathSegArrayAsString(this._list)); - - this._pathElementMutationObserver.observe(this._pathElement, this._mutationObserverConfig); - }; - - window.SVGPathSegList.prototype.segmentChanged = function (pathSeg) { - this._writeListToPath(); - }; - - window.SVGPathSegList.prototype.clear = function () { - this._checkPathSynchronizedToList(); - - this._list.forEach(function (pathSeg) { - pathSeg._owningPathSegList = null; - }); - - this._list = []; - - this._writeListToPath(); - }; - - window.SVGPathSegList.prototype.initialize = function (newItem) { - this._checkPathSynchronizedToList(); - - this._list = [newItem]; - newItem._owningPathSegList = this; - - this._writeListToPath(); - - return newItem; - }; - - window.SVGPathSegList.prototype._checkValidIndex = function (index) { - if (isNaN(index) || index < 0 || index >= this.numberOfItems) throw "INDEX_SIZE_ERR"; - }; - - window.SVGPathSegList.prototype.getItem = function (index) { - this._checkPathSynchronizedToList(); - - this._checkValidIndex(index); - - return this._list[index]; - }; - - window.SVGPathSegList.prototype.insertItemBefore = function (newItem, index) { - this._checkPathSynchronizedToList(); - - if (index > this.numberOfItems) index = this.numberOfItems; - - if (newItem._owningPathSegList) { - newItem = newItem.clone(); - } - - this._list.splice(index, 0, newItem); - - newItem._owningPathSegList = this; - - this._writeListToPath(); - - return newItem; - }; - - window.SVGPathSegList.prototype.replaceItem = function (newItem, index) { - this._checkPathSynchronizedToList(); - - if (newItem._owningPathSegList) { - newItem = newItem.clone(); - } - - this._checkValidIndex(index); - - this._list[index] = newItem; - newItem._owningPathSegList = this; - - this._writeListToPath(); - - return newItem; - }; - - window.SVGPathSegList.prototype.removeItem = function (index) { - this._checkPathSynchronizedToList(); - - this._checkValidIndex(index); - - const item = this._list[index]; - - this._list.splice(index, 1); - - this._writeListToPath(); - - return item; - }; - - window.SVGPathSegList.prototype.appendItem = function (newItem) { - this._checkPathSynchronizedToList(); - - if (newItem._owningPathSegList) { - newItem = newItem.clone(); - } - - this._list.push(newItem); - - newItem._owningPathSegList = this; - - this._writeListToPath(); - - return newItem; - }; - - window.SVGPathSegList._pathSegArrayAsString = function (pathSegArray) { - let string = ""; - let first = true; - pathSegArray.forEach(function (pathSeg) { - if (first) { - first = false; - string += pathSeg._asPathString(); - } else { - string += " " + pathSeg._asPathString(); - } - }); - return string; - }; - - window.SVGPathSegList.prototype._parsePath = function (string) { - if (!string || string.length == 0) return []; - const owningPathSegList = this; - - const Builder = function () { - this.pathSegList = []; - }; - - Builder.prototype.appendSegment = function (pathSeg) { - this.pathSegList.push(pathSeg); - }; - - const Source = function (string) { - this._string = string; - this._currentIndex = 0; - this._endIndex = this._string.length; - this._previousCommand = window.SVGPathSeg.PATHSEG_UNKNOWN; - - this._skipOptionalSpaces(); - }; - - Source.prototype._isCurrentSpace = function () { - const character = this._string[this._currentIndex]; - return character <= " " && (character == " " || character == "\n" || character == "\t" || character == "\r" || character == "\f"); - }; - - Source.prototype._skipOptionalSpaces = function () { - while (this._currentIndex < this._endIndex && this._isCurrentSpace()) this._currentIndex++; - - return this._currentIndex < this._endIndex; - }; - - Source.prototype._skipOptionalSpacesOrDelimiter = function () { - if (this._currentIndex < this._endIndex && !this._isCurrentSpace() && this._string.charAt(this._currentIndex) != ",") return false; - - if (this._skipOptionalSpaces()) { - if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == ",") { - this._currentIndex++; - - this._skipOptionalSpaces(); - } - } - - return this._currentIndex < this._endIndex; - }; - - Source.prototype.hasMoreData = function () { - return this._currentIndex < this._endIndex; - }; - - Source.prototype.peekSegmentType = function () { - const lookahead = this._string[this._currentIndex]; - return this._pathSegTypeFromChar(lookahead); - }; - - Source.prototype._pathSegTypeFromChar = function (lookahead) { - switch (lookahead) { - case "Z": - case "z": - return window.SVGPathSeg.PATHSEG_CLOSEPATH; - - case "M": - return window.SVGPathSeg.PATHSEG_MOVETO_ABS; - - case "m": - return window.SVGPathSeg.PATHSEG_MOVETO_REL; - - case "L": - return window.SVGPathSeg.PATHSEG_LINETO_ABS; - - case "l": - return window.SVGPathSeg.PATHSEG_LINETO_REL; - - case "C": - return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS; - - case "c": - return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL; - - case "Q": - return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS; - - case "q": - return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL; - - case "A": - return window.SVGPathSeg.PATHSEG_ARC_ABS; - - case "a": - return window.SVGPathSeg.PATHSEG_ARC_REL; - - case "H": - return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS; - - case "h": - return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL; - - case "V": - return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS; - - case "v": - return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL; - - case "S": - return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS; - - case "s": - return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL; - - case "T": - return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS; - - case "t": - return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL; - - default: - return window.SVGPathSeg.PATHSEG_UNKNOWN; - } - }; - - Source.prototype._nextCommandHelper = function (lookahead, previousCommand) { - if ((lookahead == "+" || lookahead == "-" || lookahead == "." || lookahead >= "0" && lookahead <= "9") && previousCommand != window.SVGPathSeg.PATHSEG_CLOSEPATH) { - if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_ABS) return window.SVGPathSeg.PATHSEG_LINETO_ABS; - if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_REL) return window.SVGPathSeg.PATHSEG_LINETO_REL; - return previousCommand; - } - - return window.SVGPathSeg.PATHSEG_UNKNOWN; - }; - - Source.prototype.initialCommandIsMoveTo = function () { - if (!this.hasMoreData()) return true; - const command = this.peekSegmentType(); - return command == window.SVGPathSeg.PATHSEG_MOVETO_ABS || command == window.SVGPathSeg.PATHSEG_MOVETO_REL; - }; - - Source.prototype._parseNumber = function () { - let exponent = 0; - let integer = 0; - let frac = 1; - let decimal = 0; - let sign = 1; - let expsign = 1; - const startIndex = this._currentIndex; - - this._skipOptionalSpaces(); - - if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == "+") this._currentIndex++;else if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == "-") { - this._currentIndex++; - sign = -1; - } - if (this._currentIndex == this._endIndex || (this._string.charAt(this._currentIndex) < "0" || this._string.charAt(this._currentIndex) > "9") && this._string.charAt(this._currentIndex) != ".") return undefined; - const startIntPartIndex = this._currentIndex; - - while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= "0" && this._string.charAt(this._currentIndex) <= "9") this._currentIndex++; - - if (this._currentIndex != startIntPartIndex) { - let scanIntPartIndex = this._currentIndex - 1; - let multiplier = 1; - - while (scanIntPartIndex >= startIntPartIndex) { - integer += multiplier * (this._string.charAt(scanIntPartIndex--) - "0"); - multiplier *= 10; - } - } - - if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == ".") { - this._currentIndex++; - if (this._currentIndex >= this._endIndex || this._string.charAt(this._currentIndex) < "0" || this._string.charAt(this._currentIndex) > "9") return undefined; - - while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= "0" && this._string.charAt(this._currentIndex) <= "9") { - frac *= 10; - decimal += (this._string.charAt(this._currentIndex) - "0") / frac; - this._currentIndex += 1; - } - } - - if (this._currentIndex != startIndex && this._currentIndex + 1 < this._endIndex && (this._string.charAt(this._currentIndex) == "e" || this._string.charAt(this._currentIndex) == "E") && this._string.charAt(this._currentIndex + 1) != "x" && this._string.charAt(this._currentIndex + 1) != "m") { - this._currentIndex++; - - if (this._string.charAt(this._currentIndex) == "+") { - this._currentIndex++; - } else if (this._string.charAt(this._currentIndex) == "-") { - this._currentIndex++; - expsign = -1; - } - - if (this._currentIndex >= this._endIndex || this._string.charAt(this._currentIndex) < "0" || this._string.charAt(this._currentIndex) > "9") return undefined; - - while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= "0" && this._string.charAt(this._currentIndex) <= "9") { - exponent *= 10; - exponent += this._string.charAt(this._currentIndex) - "0"; - this._currentIndex++; - } - } - - let number = integer + decimal; - number *= sign; - if (exponent) number *= Math.pow(10, expsign * exponent); - if (startIndex == this._currentIndex) return undefined; - - this._skipOptionalSpacesOrDelimiter(); - - return number; - }; - - Source.prototype._parseArcFlag = function () { - if (this._currentIndex >= this._endIndex) return undefined; - let flag = false; - - const flagChar = this._string.charAt(this._currentIndex++); - - if (flagChar == "0") flag = false;else if (flagChar == "1") flag = true;else return undefined; - - this._skipOptionalSpacesOrDelimiter(); - - return flag; - }; - - Source.prototype.parseSegment = function () { - const lookahead = this._string[this._currentIndex]; - - let command = this._pathSegTypeFromChar(lookahead); - - if (command == window.SVGPathSeg.PATHSEG_UNKNOWN) { - if (this._previousCommand == window.SVGPathSeg.PATHSEG_UNKNOWN) return null; - command = this._nextCommandHelper(lookahead, this._previousCommand); - if (command == window.SVGPathSeg.PATHSEG_UNKNOWN) return null; - } else { - this._currentIndex++; - } - - this._previousCommand = command; - let points; - - switch (command) { - case window.SVGPathSeg.PATHSEG_MOVETO_REL: - return new window.SVGPathSegMovetoRel(owningPathSegList, this._parseNumber(), this._parseNumber()); - - case window.SVGPathSeg.PATHSEG_MOVETO_ABS: - return new window.SVGPathSegMovetoAbs(owningPathSegList, this._parseNumber(), this._parseNumber()); - - case window.SVGPathSeg.PATHSEG_LINETO_REL: - return new window.SVGPathSegLinetoRel(owningPathSegList, this._parseNumber(), this._parseNumber()); - - case window.SVGPathSeg.PATHSEG_LINETO_ABS: - return new window.SVGPathSegLinetoAbs(owningPathSegList, this._parseNumber(), this._parseNumber()); - - case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL: - return new window.SVGPathSegLinetoHorizontalRel(owningPathSegList, this._parseNumber()); - - case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS: - return new window.SVGPathSegLinetoHorizontalAbs(owningPathSegList, this._parseNumber()); - - case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL: - return new window.SVGPathSegLinetoVerticalRel(owningPathSegList, this._parseNumber()); - - case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS: - return new window.SVGPathSegLinetoVerticalAbs(owningPathSegList, this._parseNumber()); - - case window.SVGPathSeg.PATHSEG_CLOSEPATH: - this._skipOptionalSpaces(); - - return new window.SVGPathSegClosePath(owningPathSegList); - - case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL: - points = { - x1: this._parseNumber(), - y1: this._parseNumber(), - x2: this._parseNumber(), - y2: this._parseNumber(), - x: this._parseNumber(), - y: this._parseNumber() - }; - return new window.SVGPathSegCurvetoCubicRel(owningPathSegList, points.x, points.y, points.x1, points.y1, points.x2, points.y2); - - case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS: - points = { - x1: this._parseNumber(), - y1: this._parseNumber(), - x2: this._parseNumber(), - y2: this._parseNumber(), - x: this._parseNumber(), - y: this._parseNumber() - }; - return new window.SVGPathSegCurvetoCubicAbs(owningPathSegList, points.x, points.y, points.x1, points.y1, points.x2, points.y2); - - case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL: - points = { - x2: this._parseNumber(), - y2: this._parseNumber(), - x: this._parseNumber(), - y: this._parseNumber() - }; - return new window.SVGPathSegCurvetoCubicSmoothRel(owningPathSegList, points.x, points.y, points.x2, points.y2); - - case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS: - points = { - x2: this._parseNumber(), - y2: this._parseNumber(), - x: this._parseNumber(), - y: this._parseNumber() - }; - return new window.SVGPathSegCurvetoCubicSmoothAbs(owningPathSegList, points.x, points.y, points.x2, points.y2); - - case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL: - points = { - x1: this._parseNumber(), - y1: this._parseNumber(), - x: this._parseNumber(), - y: this._parseNumber() - }; - return new window.SVGPathSegCurvetoQuadraticRel(owningPathSegList, points.x, points.y, points.x1, points.y1); - - case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS: - points = { - x1: this._parseNumber(), - y1: this._parseNumber(), - x: this._parseNumber(), - y: this._parseNumber() - }; - return new window.SVGPathSegCurvetoQuadraticAbs(owningPathSegList, points.x, points.y, points.x1, points.y1); - - case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL: - return new window.SVGPathSegCurvetoQuadraticSmoothRel(owningPathSegList, this._parseNumber(), this._parseNumber()); - - case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS: - return new window.SVGPathSegCurvetoQuadraticSmoothAbs(owningPathSegList, this._parseNumber(), this._parseNumber()); - - case window.SVGPathSeg.PATHSEG_ARC_REL: - points = { - x1: this._parseNumber(), - y1: this._parseNumber(), - arcAngle: this._parseNumber(), - arcLarge: this._parseArcFlag(), - arcSweep: this._parseArcFlag(), - x: this._parseNumber(), - y: this._parseNumber() - }; - return new window.SVGPathSegArcRel(owningPathSegList, points.x, points.y, points.x1, points.y1, points.arcAngle, points.arcLarge, points.arcSweep); - - case window.SVGPathSeg.PATHSEG_ARC_ABS: - points = { - x1: this._parseNumber(), - y1: this._parseNumber(), - arcAngle: this._parseNumber(), - arcLarge: this._parseArcFlag(), - arcSweep: this._parseArcFlag(), - x: this._parseNumber(), - y: this._parseNumber() - }; - return new window.SVGPathSegArcAbs(owningPathSegList, points.x, points.y, points.x1, points.y1, points.arcAngle, points.arcLarge, points.arcSweep); - - default: - throw "Unknown path seg type."; - } - }; - - const builder = new Builder(); - const source = new Source(string); - if (!source.initialCommandIsMoveTo()) return []; - - while (source.hasMoreData()) { - const pathSeg = source.parseSegment(); - if (!pathSeg) return []; - builder.appendSegment(pathSeg); - } - - return builder.pathSegList; - }; - } - } catch (e) { - console.warn("An error occurred in tsParticles pathseg polyfill. If the Polygon Mask is not working, please open an issue here: https://github.com/matteobruni/tsparticles", e); - } -})(); - -/***/ }) - -}]); \ No newline at end of file diff --git a/src/ui/static/js/cache.js b/src/ui/static/js/cache.js index eed9e62eb..92f8f178f 100644 --- a/src/ui/static/js/cache.js +++ b/src/ui/static/js/cache.js @@ -16,7 +16,9 @@ class Download { this.listContainer.addEventListener("click", (e) => { try { if ( - e.target.closest("button").hasAttribute(`data-${this.prefix}-download`) + e.target + .closest("button") + .hasAttribute(`data-${this.prefix}-download`) ) { const btnEl = e.target.closest("button"); const jobName = btnEl.getAttribute("data-cache-download"); @@ -31,8 +33,8 @@ class Download { window.open( `${location.href.replace( "cache", - "jobs" - )}/download?job_name=${jobName}&file_name=${fileName}` + "jobs", + )}/download?job_name=${jobName}&file_name=${fileName}`, ); } } diff --git a/src/ui/static/js/configs.js b/src/ui/static/js/configs.js index 280cacc4c..c71634031 100644 --- a/src/ui/static/js/configs.js +++ b/src/ui/static/js/configs.js @@ -1,11 +1,11 @@ -import { - FolderNav, - FolderEditor, - FolderModal, - FolderDropdown, -} from "./utils/file.manager.js"; - -const setModal = new FolderModal("configs"); -const setEditor = new FolderEditor(); -const setFolderNav = new FolderNav("configs"); -const setDropdown = new FolderDropdown("configs"); +import { + FolderNav, + FolderEditor, + FolderModal, + FolderDropdown, +} from "./utils/file.manager.js"; + +const setModal = new FolderModal("configs"); +const setEditor = new FolderEditor(); +const setFolderNav = new FolderNav("configs"); +const setDropdown = new FolderDropdown("configs"); diff --git a/src/ui/static/js/global.js b/src/ui/static/js/global.js index ad6050463..1d8effff3 100644 --- a/src/ui/static/js/global.js +++ b/src/ui/static/js/global.js @@ -1,317 +1,318 @@ -import { Checkbox, Select, Password, DisabledPop } from "./utils/form.js"; - -class Menu { - constructor() { - this.sidebarEl = document.querySelector("[data-sidebar-menu]"); - this.toggleBtn = document.querySelector("[data-sidebar-menu-toggle]"); - this.closeBtn = document.querySelector("[data-sidebar-menu-close]"); - - this.toggleBtn.addEventListener("click", this.toggle.bind(this)); - this.closeBtn.addEventListener("click", this.close.bind(this)); - this.init(); - } - - init() { - window.addEventListener("click", (e) => { - try { - if ( - e.target.closest("aside").hasAttribute("data-sidebar-menu") && - e.target.closest("button").getAttribute("role") === "tab" - ) { - this.close(); - } - } catch (err) {} - }); - } - - toggle() { - this.sidebarEl.classList.toggle("-translate-x-full"); - } - - close() { - this.sidebarEl.classList.add("-translate-x-full"); - } -} - -class News { - constructor() { - this.BASE_URL = "https://www.bunkerweb.io/"; - this.init(); - } - - init() { - window.addEventListener("load", async () => { - try { - const res = await fetch("https://www.bunkerweb.io/api/posts/0/2", { - headers: { - method: "GET", - }, - }); - return await this.render(res); - } catch (err) {} - }); - } - - render(lastNews) { - const newsContainer = document.querySelector("[data-news-container]"); - //remove default message - newsContainer.textContent = ""; - //render last news - lastNews.forEach((news) => { - //get info - const slug = news.slug; - const img = news.photo.url; - const excerpt = news.excerpt; - const tags = news.tags; - const date = news.date; - const lastUpdate = news.lastUpdate; - //create html card from infos - const cardHTML = this.template( - slug, - img, - excerpt, - tags, - date, - lastUpdate - ); - //add to DOM - document - .querySelector("[data-news-container]") - .insertAdjacentHTML("afterbegin", cardHTML); - }); - } - - template(slug, img, excerpt, tags, date, lastUpdate) { - //loop on tags to get list - let tagList = ""; - tags.forEach((tag) => { - tagList += ` - ${tag.name} - `; - }); - //create card - const card = ` -
-
- image -

{{ post['title'] }}

-
-
-
- ${excerpt} -
-
- ${tagList} -
- -
- Posted on : ${date} - {% if post["updatedAt"] %} - Last update : ${lastUpdate} - {%endif%} -
-
-
`; - return card; - } -} - -class Sidebar { - constructor(elAtt, btnOpenAtt, btnCloseAtt) { - this.sidebarEl = document.querySelector(elAtt); - this.openBtn = document.querySelector(btnOpenAtt); - this.closeBtn = document.querySelector(btnCloseAtt); - this.openBtn.addEventListener("click", this.open.bind(this)); - this.closeBtn.addEventListener("click", this.close.bind(this)); - } - - open() { - this.sidebarEl.classList.add("translate-x-0"); - this.sidebarEl.classList.remove("translate-x-90"); - } - - close() { - this.sidebarEl.classList.add("translate-x-90"); - this.sidebarEl.classList.remove("translate-x-0"); - } -} - -class darkMode { - constructor() { - this.htmlEl = document.querySelector("html"); - this.darkToggleEl = document.querySelector("[data-dark-toggle]"); - this.darkToggleLabel = document.querySelector("[data-dark-toggle-label]"); - this.csrf = document.querySelector("input#csrf_token"); - this.init(); - } - - init() { - this.darkToggleEl.addEventListener("change", (e) => { - this.toggle(); - this.saveMode(); - }); - } - - toggle() { - document.querySelector("html").classList.toggle("dark"); - this.darkToggleLabel.textContent = this.darkToggleEl.checked - ? "dark mode" - : "light mode"; - } - - async saveMode() { - const isDark = this.darkToggleEl.checked ? "true" : "false"; - const data = { - method: "POST", - headers: { - Accept: "application/json", - "Content-Type": "application/json", - "X-CSRF-Token": this.csrf.value, - }, - body: JSON.stringify({ darkmode: isDark }), - }; - const send = await fetch( - `${location.href.split("/").slice(0, -1).join("/")}/darkmode`, - data - ); - } -} - -class FlashMsg { - constructor() { - this.openBtn = document.querySelector("[data-flash-sidebar-open]"); - this.flashCount = document.querySelector("[data-flash-count]"); - this.isMsgCheck = false; - this.init(); - } - - init() { - //animate message button if message + never opened - window.addEventListener("load", (e) => { - if (Number(this.flashCount.textContent) > 0) this.animeBtn(); - }); - //stop animate if clicked once - this.openBtn.addEventListener("click", (e) => { - try { - if ( - e.target.closest("button").hasAttribute("data-flash-sidebar-open") - ) { - this.isMsgCheck = true; - } - } catch (err) {} - }); - //remove flash message and change count - window.addEventListener("click", (e) => { - try { - if ( - e.target.closest("button").hasAttribute("data-close-flash-message") - ) { - //remove logic - const closeBtn = e.target.closest("button"); - const flashEl = closeBtn.closest("[data-flash-message]"); - flashEl.remove(); - //update count - this.flashCount.textContent = document.querySelectorAll( - "[data-flash-message]" - ).length; - } - } catch (err) {} - }); - } - - animeBtn() { - this.openBtn.classList.add("rotate-12"); - - setTimeout(() => { - this.openBtn.classList.remove("rotate-12"); - this.openBtn.classList.add("-rotate-12"); - }, 150); - - setTimeout(() => { - this.openBtn.classList.remove("-rotate-12"); - }, 300); - - setTimeout(() => { - if (!this.isMsgCheck) { - this.animeBtn(); - } - }, 1500); - } -} - -class Loader { - constructor() { - this.menuContainer = document.querySelector("[data-menu-container]"); - this.logoContainer = document.querySelector("[data-loader]"); - this.logoEl = document.querySelector("[data-loader-img]"); - this.isLoading = true; - this.init(); - } - - init() { - this.loading(); - window.addEventListener("load", (e) => { - setTimeout(() => { - this.logoContainer.classList.add("opacity-0"); - }, 350); - - setTimeout(() => { - this.isLoading = false; - this.logoContainer.classList.add("hidden"); - }, 650); - - setTimeout(() => { - this.logoContainer.remove(); - }, 800); - }); - } - - loading() { - if ((this.isLoading = true)) { - setTimeout(() => { - this.logoEl.classList.toggle("scale-105"); - this.loading(); - }, 300); - } - } -} - -const setLoader = new Loader(); -const setMenu = new Menu(); -const setNewsSidebar = new Sidebar( - "[data-sidebar-info]", - "[data-sidebar-info-open]", - "[data-sidebar-info-close]" -); - -const setCheckbox = new Checkbox(); -const setSelect = new Select(); -const setPassword = new Password(); -const setDisabledPop = new DisabledPop(); - -const setFlashSidebar = new Sidebar( - "[data-flash-sidebar]", - "[data-flash-sidebar-open]", - "[data-flash-sidebar-close]" -); -const setNews = new News(); -const setDarkM = new darkMode(); -const setFlash = new FlashMsg(); +import { Checkbox, Select, Password, DisabledPop } from "./utils/form.js"; + +class Menu { + constructor() { + this.sidebarEl = document.querySelector("[data-sidebar-menu]"); + this.toggleBtn = document.querySelector("[data-sidebar-menu-toggle]"); + this.closeBtn = document.querySelector("[data-sidebar-menu-close]"); + + this.toggleBtn.addEventListener("click", this.toggle.bind(this)); + this.closeBtn.addEventListener("click", this.close.bind(this)); + this.init(); + } + + init() { + window.addEventListener("click", (e) => { + try { + if ( + e.target.closest("aside").hasAttribute("data-sidebar-menu") && + e.target.closest("button").getAttribute("role") === "tab" + ) { + this.close(); + } + } catch (err) {} + }); + } + + toggle() { + this.sidebarEl.classList.toggle("-translate-x-full"); + } + + close() { + this.sidebarEl.classList.add("-translate-x-full"); + } +} + +class News { + constructor() { + this.BASE_URL = "https://www.bunkerweb.io/"; + this.init(); + } + + init() { + window.addEventListener("load", async () => { + try { + const res = await fetch("https://www.bunkerweb.io/api/posts/0/2", { + headers: { + method: "GET", + }, + }); + return await this.render(res); + } catch (err) {} + }); + } + + render(lastNews) { + const newsContainer = document.querySelector("[data-news-container]"); + //remove default message + newsContainer.textContent = ""; + //render last news + lastNews.forEach((news) => { + //get info + const slug = news.slug; + const img = news.photo.url; + const excerpt = news.excerpt; + const tags = news.tags; + const date = news.date; + const lastUpdate = news.lastUpdate; + //create html card from infos + const cardHTML = this.template( + slug, + img, + excerpt, + tags, + date, + lastUpdate + ); + let cleanHTML = DOMPurify.sanitize(cardHTML); + //add to DOM + document + .querySelector("[data-news-container]") + .insertAdjacentHTML("afterbegin", cleanHTML); + }); + } + + template(slug, img, excerpt, tags, date, lastUpdate) { + //loop on tags to get list + let tagList = ""; + tags.forEach((tag) => { + tagList += ` + ${tag.name} + `; + }); + //create card + const card = ` +
+
+ image +

{{ post['title'] }}

+
+
+
+ ${excerpt} +
+
+ ${tagList} +
+ +
+ Posted on : ${date} + {% if post["updatedAt"] %} + Last update : ${lastUpdate} + {%endif%} +
+
+
`; + return card; + } +} + +class Sidebar { + constructor(elAtt, btnOpenAtt, btnCloseAtt) { + this.sidebarEl = document.querySelector(elAtt); + this.openBtn = document.querySelector(btnOpenAtt); + this.closeBtn = document.querySelector(btnCloseAtt); + this.openBtn.addEventListener("click", this.open.bind(this)); + this.closeBtn.addEventListener("click", this.close.bind(this)); + } + + open() { + this.sidebarEl.classList.add("translate-x-0"); + this.sidebarEl.classList.remove("translate-x-90"); + } + + close() { + this.sidebarEl.classList.add("translate-x-90"); + this.sidebarEl.classList.remove("translate-x-0"); + } +} + +class darkMode { + constructor() { + this.htmlEl = document.querySelector("html"); + this.darkToggleEl = document.querySelector("[data-dark-toggle]"); + this.darkToggleLabel = document.querySelector("[data-dark-toggle-label]"); + this.csrf = document.querySelector("input#csrf_token"); + this.init(); + } + + init() { + this.darkToggleEl.addEventListener("change", (e) => { + this.toggle(); + this.saveMode(); + }); + } + + toggle() { + document.querySelector("html").classList.toggle("dark"); + this.darkToggleLabel.textContent = this.darkToggleEl.checked + ? "dark mode" + : "light mode"; + } + + async saveMode() { + const isDark = this.darkToggleEl.checked ? "true" : "false"; + const data = { + method: "POST", + headers: { + Accept: "application/json", + "Content-Type": "application/json", + "X-CSRF-Token": this.csrf.value, + }, + body: JSON.stringify({ darkmode: isDark }), + }; + const send = await fetch( + `${location.href.split("/").slice(0, -1).join("/")}/darkmode`, + data + ); + } +} + +class FlashMsg { + constructor() { + this.openBtn = document.querySelector("[data-flash-sidebar-open]"); + this.flashCount = document.querySelector("[data-flash-count]"); + this.isMsgCheck = false; + this.init(); + } + + init() { + //animate message button if message + never opened + window.addEventListener("load", (e) => { + if (Number(this.flashCount.textContent) > 0) this.animeBtn(); + }); + //stop animate if clicked once + this.openBtn.addEventListener("click", (e) => { + try { + if ( + e.target.closest("button").hasAttribute("data-flash-sidebar-open") + ) { + this.isMsgCheck = true; + } + } catch (err) {} + }); + //remove flash message and change count + window.addEventListener("click", (e) => { + try { + if ( + e.target.closest("button").hasAttribute("data-close-flash-message") + ) { + //remove logic + const closeBtn = e.target.closest("button"); + const flashEl = closeBtn.closest("[data-flash-message]"); + flashEl.remove(); + //update count + this.flashCount.textContent = document.querySelectorAll( + "[data-flash-message]" + ).length; + } + } catch (err) {} + }); + } + + animeBtn() { + this.openBtn.classList.add("rotate-12"); + + setTimeout(() => { + this.openBtn.classList.remove("rotate-12"); + this.openBtn.classList.add("-rotate-12"); + }, 150); + + setTimeout(() => { + this.openBtn.classList.remove("-rotate-12"); + }, 300); + + setTimeout(() => { + if (!this.isMsgCheck) { + this.animeBtn(); + } + }, 1500); + } +} + +class Loader { + constructor() { + this.menuContainer = document.querySelector("[data-menu-container]"); + this.logoContainer = document.querySelector("[data-loader]"); + this.logoEl = document.querySelector("[data-loader-img]"); + this.isLoading = true; + this.init(); + } + + init() { + this.loading(); + window.addEventListener("load", (e) => { + setTimeout(() => { + this.logoContainer.classList.add("opacity-0"); + }, 350); + + setTimeout(() => { + this.isLoading = false; + this.logoContainer.classList.add("hidden"); + }, 650); + + setTimeout(() => { + this.logoContainer.remove(); + }, 800); + }); + } + + loading() { + if ((this.isLoading = true)) { + setTimeout(() => { + this.logoEl.classList.toggle("scale-105"); + this.loading(); + }, 300); + } + } +} + +const setLoader = new Loader(); +const setMenu = new Menu(); +const setNewsSidebar = new Sidebar( + "[data-sidebar-info]", + "[data-sidebar-info-open]", + "[data-sidebar-info-close]" +); + +const setCheckbox = new Checkbox(); +const setSelect = new Select(); +const setPassword = new Password(); +const setDisabledPop = new DisabledPop(); + +const setFlashSidebar = new Sidebar( + "[data-flash-sidebar]", + "[data-flash-sidebar-open]", + "[data-flash-sidebar-close]" +); +const setNews = new News(); +const setDarkM = new darkMode(); +const setFlash = new FlashMsg(); diff --git a/src/ui/static/js/global_config.js b/src/ui/static/js/global_config.js index cd4fd1dd1..80ec17d98 100644 --- a/src/ui/static/js/global_config.js +++ b/src/ui/static/js/global_config.js @@ -1,35 +1,35 @@ -import { - Popover, - Tabs, - FormatValue, - FilterSettings, -} from "./utils/settings.js"; - -class Multiple { - constructor(prefix) { - this.prefix = prefix; - this.init(); - } - //hide multiples handler if no multiple setting on plugin - init() { - //hide multiple btn if no multiple exist on a plugin - const multiples = document.querySelectorAll( - `[data-${this.prefix}-settings-multiple]` - ); - multiples.forEach((container) => { - if (container.querySelectorAll(`[data-setting-container]`).length <= 0) - container.parentElement - .querySelector("[data-multiple-handler]") - .classList.add("hidden"); - }); - } -} - -const setPopover = new Popover("main", "global-config"); -const setTabs = new Tabs("[global-config-tabs]", "global-config"); -const format = new FormatValue(); -const setMultiple = new Multiple("global-config"); -const setFilterGlobal = new FilterSettings( - "settings-filter", - "[data-service-content='settings']" -); +import { + Popover, + Tabs, + FormatValue, + FilterSettings, +} from "./utils/settings.js"; + +class Multiple { + constructor(prefix) { + this.prefix = prefix; + this.init(); + } + //hide multiples handler if no multiple setting on plugin + init() { + //hide multiple btn if no multiple exist on a plugin + const multiples = document.querySelectorAll( + `[data-${this.prefix}-settings-multiple]`, + ); + multiples.forEach((container) => { + if (container.querySelectorAll(`[data-setting-container]`).length <= 0) + container.parentElement + .querySelector("[data-multiple-handler]") + .classList.add("hidden"); + }); + } +} + +const setPopover = new Popover("main", "global-config"); +const setTabs = new Tabs("[global-config-tabs]", "global-config"); +const format = new FormatValue(); +const setMultiple = new Multiple("global-config"); +const setFilterGlobal = new FilterSettings( + "settings-filter", + "[data-service-content='settings']", +); diff --git a/src/ui/static/js/jobs.js b/src/ui/static/js/jobs.js index d40f1046f..aaca55afb 100644 --- a/src/ui/static/js/jobs.js +++ b/src/ui/static/js/jobs.js @@ -37,7 +37,7 @@ class Dropdown { const btn = e.target.closest("button"); const btnValue = btn.getAttribute("value"); const btnSetting = btn.getAttribute( - `data-${this.prefix}-setting-select-dropdown-btn` + `data-${this.prefix}-setting-select-dropdown-btn`, ); //stop if same value to avoid new fetching const isSameVal = this.isSameValue(btnSetting, btnValue); @@ -61,7 +61,7 @@ class Dropdown { closeAllDrop() { const drops = document.querySelectorAll( - `[data-${this.prefix}-setting-select-dropdown]` + `[data-${this.prefix}-setting-select-dropdown]`, ); drops.forEach((drop) => { drop.classList.add("hidden"); @@ -69,8 +69,8 @@ class Dropdown { document .querySelector( `svg[data-${this.prefix}-setting-select="${drop.getAttribute( - `data-${this.prefix}-setting-select-dropdown` - )}"]` + `data-${this.prefix}-setting-select-dropdown`, + )}"]`, ) .classList.remove("rotate-180"); }); @@ -78,7 +78,7 @@ class Dropdown { isSameValue(btnSetting, value) { const selectCustom = document.querySelector( - `[data-${this.prefix}-setting-select-text="${btnSetting}"]` + `[data-${this.prefix}-setting-select-text="${btnSetting}"]`, ); const currVal = selectCustom.textContent; return currVal === value ? true : false; @@ -86,30 +86,30 @@ class Dropdown { setSelectNewValue(btnSetting, value) { const selectCustom = document.querySelector( - `[data-${this.prefix}-setting-select="${btnSetting}"]` + `[data-${this.prefix}-setting-select="${btnSetting}"]`, ); selectCustom.querySelector( - `[data-${this.prefix}-setting-select-text]` + `[data-${this.prefix}-setting-select-text]`, ).textContent = value; } hideDropdown(btnSetting) { //hide dropdown const dropdownEl = document.querySelector( - `[data-${this.prefix}-setting-select-dropdown="${btnSetting}"]` + `[data-${this.prefix}-setting-select-dropdown="${btnSetting}"]`, ); dropdownEl.classList.add("hidden"); dropdownEl.classList.remove("flex"); //svg effect const dropdownChevron = document.querySelector( - `svg[data-${this.prefix}-setting-select="${btnSetting}"]` + `svg[data-${this.prefix}-setting-select="${btnSetting}"]`, ); dropdownChevron.classList.remove("rotate-180"); } changeDropBtnStyle(btnSetting, selectedBtn) { const dropdownEl = document.querySelector( - `[data-${this.prefix}-setting-select-dropdown="${btnSetting}"]` + `[data-${this.prefix}-setting-select-dropdown="${btnSetting}"]`, ); //reset dropdown btns const btnEls = dropdownEl.querySelectorAll("button"); @@ -119,7 +119,7 @@ class Dropdown { "bg-primary", "dark:bg-primary", "text-gray-300", - "text-gray-300" + "text-gray-300", ); btn.classList.add("bg-white", "dark:bg-slate-700", "text-gray-700"); }); @@ -127,7 +127,7 @@ class Dropdown { selectedBtn.classList.remove( "bg-white", "dark:bg-slate-700", - "text-gray-700" + "text-gray-700", ); selectedBtn.classList.add("dark:bg-primary", "bg-primary", "text-gray-300"); } @@ -138,10 +138,10 @@ class Dropdown { .getAttribute(`data-${this.prefix}-setting-select`); //toggle dropdown const dropdownEl = document.querySelector( - `[data-${this.prefix}-setting-select-dropdown="${attribut}"]` + `[data-${this.prefix}-setting-select-dropdown="${attribut}"]`, ); const dropdownChevron = document.querySelector( - `svg[data-${this.prefix}-setting-select="${attribut}"]` + `svg[data-${this.prefix}-setting-select="${attribut}"]`, ); dropdownEl.classList.toggle("hidden"); dropdownEl.classList.toggle("flex"); @@ -197,7 +197,7 @@ class Filter { setTimeout(() => { const value = document .querySelector( - `[data-${this.prefix}-setting-select-text="success"]` + `[data-${this.prefix}-setting-select-text="success"]`, ) .textContent.trim(); @@ -220,7 +220,7 @@ class Filter { setTimeout(() => { const value = document .querySelector( - `[data-${this.prefix}-setting-select-text="reload"]` + `[data-${this.prefix}-setting-select-text="reload"]`, ) .textContent.trim(); @@ -329,7 +329,7 @@ class Download { async sendFileToDL(jobName, fileName) { window.open( - `${location.href}/download?job_name=${jobName}&file_name=${fileName}` + `${location.href}/download?job_name=${jobName}&file_name=${fileName}`, ); } } diff --git a/src/ui/static/js/logs.js b/src/ui/static/js/logs.js index c52b2c89f..4bcd6ff4d 100644 --- a/src/ui/static/js/logs.js +++ b/src/ui/static/js/logs.js @@ -37,7 +37,7 @@ class Dropdown { const btn = e.target.closest("button"); const btnValue = btn.getAttribute("value"); const btnSetting = btn.getAttribute( - `data-${this.prefix}-setting-select-dropdown-btn` + `data-${this.prefix}-setting-select-dropdown-btn`, ); //stop if same value to avoid new fetching const isSameVal = this.isSameValue(btnSetting, btnValue); @@ -58,7 +58,7 @@ class Dropdown { closeAllDrop() { const drops = document.querySelectorAll( - `[data-${this.prefix}-setting-select-dropdown]` + `[data-${this.prefix}-setting-select-dropdown]`, ); drops.forEach((drop) => { drop.classList.add("hidden"); @@ -66,8 +66,8 @@ class Dropdown { document .querySelector( `svg[data-${this.prefix}-setting-select="${drop.getAttribute( - `data-${this.prefix}-setting-select-dropdown` - )}"]` + `data-${this.prefix}-setting-select-dropdown`, + )}"]`, ) .classList.remove("rotate-180"); }); @@ -75,7 +75,7 @@ class Dropdown { isSameValue(btnSetting, value) { const selectCustom = document.querySelector( - `[data-${this.prefix}-setting-select-text="${btnSetting}"]` + `[data-${this.prefix}-setting-select-text="${btnSetting}"]`, ); const currVal = selectCustom.textContent; return currVal === value ? true : false; @@ -83,30 +83,30 @@ class Dropdown { setSelectNewValue(btnSetting, value) { const selectCustom = document.querySelector( - `[data-${this.prefix}-setting-select="${btnSetting}"]` + `[data-${this.prefix}-setting-select="${btnSetting}"]`, ); selectCustom.querySelector( - `[data-${this.prefix}-setting-select-text]` + `[data-${this.prefix}-setting-select-text]`, ).textContent = value; } hideDropdown(btnSetting) { //hide dropdown const dropdownEl = document.querySelector( - `[data-${this.prefix}-setting-select-dropdown="${btnSetting}"]` + `[data-${this.prefix}-setting-select-dropdown="${btnSetting}"]`, ); dropdownEl.classList.add("hidden"); dropdownEl.classList.remove("flex"); //svg effect const dropdownChevron = document.querySelector( - `svg[data-${this.prefix}-setting-select="${btnSetting}"]` + `svg[data-${this.prefix}-setting-select="${btnSetting}"]`, ); dropdownChevron.classList.remove("rotate-180"); } changeDropBtnStyle(btnSetting, selectedBtn) { const dropdownEl = document.querySelector( - `[data-${this.prefix}-setting-select-dropdown="${btnSetting}"]` + `[data-${this.prefix}-setting-select-dropdown="${btnSetting}"]`, ); //reset dropdown btns const btnEls = dropdownEl.querySelectorAll("button"); @@ -116,7 +116,7 @@ class Dropdown { "bg-primary", "dark:bg-primary", "text-gray-300", - "text-gray-300" + "text-gray-300", ); btn.classList.add("bg-white", "dark:bg-slate-700", "text-gray-700"); }); @@ -124,7 +124,7 @@ class Dropdown { selectedBtn.classList.remove( "bg-white", "dark:bg-slate-700", - "text-gray-700" + "text-gray-700", ); selectedBtn.classList.add("dark:bg-primary", "bg-primary", "text-gray-300"); } @@ -135,10 +135,10 @@ class Dropdown { .getAttribute(`data-${this.prefix}-setting-select`); //toggle dropdown const dropdownEl = document.querySelector( - `[data-${this.prefix}-setting-select-dropdown="${attribut}"]` + `[data-${this.prefix}-setting-select-dropdown="${attribut}"]`, ); const dropdownChevron = document.querySelector( - `svg[data-${this.prefix}-setting-select="${attribut}"]` + `svg[data-${this.prefix}-setting-select="${attribut}"]`, ); dropdownEl.classList.toggle("hidden"); dropdownEl.classList.toggle("flex"); @@ -173,7 +173,7 @@ class FetchLogs { constructor(prefix = "logs") { this.prefix = prefix; this.instance = document.querySelector( - `[data-${this.prefix}-setting-select-text="instances"]` + `[data-${this.prefix}-setting-select-text="instances"]`, ); this.instanceName = ""; this.updateInp = document.querySelector("input#update-date"); @@ -188,7 +188,7 @@ class FetchLogs { this.lastUpdate = Date.now() - 86400000; this.container = document.querySelector(`[data-${this.prefix}-settings]`); this.logListContainer = document.querySelector( - `[data-${this.prefix}-list]` + `[data-${this.prefix}-list]`, ); this.submitDate = document.querySelector("button[data-submit-date]"); this.submitLive = document.querySelector("button[data-submit-live]"); @@ -218,7 +218,7 @@ class FetchLogs { "data-submit-live", this.submitLive.getAttribute("data-submit-live") === "yes" ? "no" - : "yes" + : "yes", ); if (this.submitLive.getAttribute("data-submit-live") === "yes") { @@ -314,7 +314,7 @@ class FetchLogs { .querySelector(`[data-${this.prefix}-list]`) .scrollTo( 0, - document.querySelector(`[data-${this.prefix}-list]`).scrollHeight + document.querySelector(`[data-${this.prefix}-list]`).scrollHeight, ); } @@ -323,7 +323,7 @@ class FetchLogs { //case from date defined only if (this.toDate) { res = await fetch( - `${location.href}/${this.instanceName}?from_date=${this.fromDate}&to_date=${this.toDate}` + `${location.href}/${this.instanceName}?from_date=${this.fromDate}&to_date=${this.toDate}`, ); const data = await res.json(); return await this.showLogsDate(data); @@ -331,7 +331,7 @@ class FetchLogs { //case from date and to date defined if (!this.toDate) { res = await fetch( - `${location.href}/${this.instanceName}?from_date=${this.fromDate}` + `${location.href}/${this.instanceName}?from_date=${this.fromDate}`, ); const data = await res.json(); return await this.showLogsDate(data); @@ -341,7 +341,7 @@ class FetchLogs { async getLogsSinceLastUpdate() { const response = await fetch( `${location.href}/${this.instanceName}` + - (this.lastUpdate ? `?last_update=${this.lastUpdate}` : "") + (this.lastUpdate ? `?last_update=${this.lastUpdate}` : ""), ); const data = await response.json(); return await this.showLogsLive(data); @@ -437,7 +437,7 @@ class Filter { const btn = e.target.closest("button"); const btnValue = btn.getAttribute("value"); const btnSetting = btn.getAttribute( - `data-${this.prefix}-setting-select-dropdown-btn` + `data-${this.prefix}-setting-select-dropdown-btn`, ); this.lastType = btnValue; diff --git a/src/ui/static/js/plugins.js b/src/ui/static/js/plugins.js index 805949982..3cbaa44a7 100644 --- a/src/ui/static/js/plugins.js +++ b/src/ui/static/js/plugins.js @@ -286,7 +286,9 @@ class Upload { //close fail/success log this.container.addEventListener("click", (e) => { try { - if (e.target.closest("button").hasAttribute("data-upload-message-delete")) { + if ( + e.target.closest("button").hasAttribute("data-upload-message-delete") + ) { const message = e.target.closest("div[data-upload-message]"); message.remove(); } @@ -406,7 +408,8 @@ class Upload { `; - return str; + let cleanHTML = DOMPurify.sanitize(str); + return cleanHTML; } fileFail(name, fileSize) { @@ -433,7 +436,8 @@ class Upload { `; - return str; + let cleanHTML = DOMPurify.sanitize(str); + return cleanHTML; } } @@ -445,8 +449,12 @@ class Modal { this.modalNameInp = this.modal.querySelector("input#name"); this.modalExtInp = this.modal.querySelector("input#external"); - this.modalTitle = this.modal.querySelector(`[data-${this.prefix}-modal-title]`); - this.modalTxt = this.modal.querySelector(`[data-${this.prefix}-modal-text]`); + this.modalTitle = this.modal.querySelector( + `[data-${this.prefix}-modal-title]` + ); + this.modalTxt = this.modal.querySelector( + `[data-${this.prefix}-modal-text]` + ); this.init(); } @@ -455,8 +463,9 @@ class Modal { //DELETE HANDLER try { if ( - e.target.closest("button").getAttribute(`data-${this.prefix}-action`) === - "delete" + e.target + .closest("button") + .getAttribute(`data-${this.prefix}-action`) === "delete" ) { const btnEl = e.target.closest("button"); this.setModal(btnEl); @@ -469,7 +478,9 @@ class Modal { //CLOSE MODAL HANDLER try { if ( - e.target.closest("button").hasAttribute(`data-${this.prefix}-modal-close`) + e.target + .closest("button") + .hasAttribute(`data-${this.prefix}-modal-close`) ) { this.hideModal(); } diff --git a/src/ui/static/js/services.js b/src/ui/static/js/services.js index 27ff5bc2f..6f1948aa1 100644 --- a/src/ui/static/js/services.js +++ b/src/ui/static/js/services.js @@ -1,871 +1,871 @@ -import { - Popover, - Tabs, - FormatValue, - FilterSettings, -} from "./utils/settings.js"; - -class ServiceModal { - constructor() { - //modal elements - this.modal = document.querySelector("[data-services-modal]"); - this.modalTitle = this.modal.querySelector("[data-services-modal-title]"); - this.modalTabs = this.modal.querySelector(["[data-services-tabs]"]); - this.modalTabsHeader = this.modal.querySelector([ - "[data-services-tabs-header]", - ]); - - this.modalCard = this.modal.querySelector("[data-services-modal-card]"); - //modal forms - this.formNewEdit = this.modal.querySelector("[data-services-modal-form]"); - this.formDelete = this.modal.querySelector( - "[data-services-modal-form-delete]" - ); - this.submitBtn = document.querySelector( - "button[data-services-modal-submit]" - ); - //container - this.container = document.querySelector("main"); - this.init(); - } - - //store default config data on DOM - //to update modal data on new button click - - getActionAndServName(target) { - const action = target - .closest("button") - .getAttribute("data-services-action"); - const serviceName = target - .closest("button") - .getAttribute("data-services-name"); - - return [action, serviceName]; - } - - init() { - this.modal.addEventListener("click", (e) => { - //close - try { - if ( - e.target.closest("button").hasAttribute("data-services-modal-close") - ) { - this.closeModal(); - } - } catch (err) {} - }); - - this.container.addEventListener("click", (e) => { - //edit action - try { - if ( - e.target.closest("button").getAttribute("data-services-action") === - "edit" - ) { - //set form info and right form - const [action, serviceName] = this.getActionAndServName(e.target); - this.setForm(action, serviceName, this.formNewEdit); - //get service data and parse it - //multiple type logic is launch at same time on relate class - const servicesSettings = e.target - .closest("[data-services-service]") - .querySelector("[data-services-settings]") - .getAttribute("data-value"); - const obj = JSON.parse(servicesSettings); - this.updateModalData(obj); - //show modal - this.resetFilterInp(); - this.changeSubmitBtn("EDIT", "edit-btn"); - this.openModal(); - } - } catch (err) {} - //new action - try { - if ( - e.target.closest("button").getAttribute("data-services-action") === - "new" - ) { - //set form info and right form - const [action, serviceName] = this.getActionAndServName(e.target); - this.setForm(action, serviceName, this.formNewEdit); - //set default value with method default - this.setSettingsDefault(); - //server name is unset - const inpServName = document.querySelector("input#SERVER_NAME"); - inpServName.getAttribute("value", ""); - inpServName.removeAttribute("disabled", ""); - inpServName.value = ""; - - //show modal - this.resetFilterInp(); - this.changeSubmitBtn("CREATE", "valid-btn"); - this.openModal(); - } - } catch (err) {} - //delete action - try { - if ( - e.target.closest("button").getAttribute("data-services-action") === - "delete" - ) { - //set form info and right form - const [action, serviceName] = this.getActionAndServName(e.target); - this.setForm(action, serviceName, this.formDelete); - //show modal - this.openModal(); - } - } catch (err) {} - }); - } - - resetFilterInp() { - const inpFilter = document.querySelector('input[name="settings-filter"]'); - inpFilter.value = ""; - inpFilter.dispatchEvent(new Event("input")); - } - - changeSubmitBtn(text, btnType) { - this.submitBtn.textContent = text; - this.submitBtn.classList.remove( - "delete-btn", - "valid-btn", - "edit-btn", - "info-btn" - ); - this.submitBtn.classList.add(btnType); - } - - setSettingsDefault() { - const inps = this.modal.querySelectorAll("input"); - inps.forEach((inp) => { - //form related values are excludes - const inpName = inp.getAttribute("name"); - if ( - inpName === "csrf_token" || - inpName === "OLD_SERVER_NAME" || - inpName === "operation" || - inpName === "settings-filter" - ) - return; - - //for all other settings values - const defaultMethod = inp.getAttribute("data-default-method"); - const defaultVal = inp.getAttribute("data-default-value"); - - //SET VALUE - if (inp.getAttribute("type") === "checkbox") { - defaultVal === "yes" - ? inp.setAttribute("aria-checked", "true") - : inp.setAttribute("aria-checked", "false"); - inp.setAttribute("value", defaultVal); - inp.setAttribute("data-method", defaultMethod); - inp.checked = true; - } - - if (inp.getAttribute("type") !== "checkbox") { - inp.setAttribute("value", defaultVal); - inp.value = defaultVal; - inp.setAttribute("data-method", defaultMethod); - } - - //SET METHOD - this.setDisabledDefault(inp, defaultMethod); - }); - - const selects = this.modal.querySelectorAll("select"); - selects.forEach((select) => { - const defaultMethod = select.getAttribute("data-default-method"); - const defaultVal = select.getAttribute("data-default-value"); - //click the custom select dropdown to update select value - select.parentElement - .querySelector( - `button[data-setting-select-dropdown-btn][value='${defaultVal}']` - ) - .click(); - - //set state to custom visible el - const btnCustom = document.querySelector( - `[data-setting-select=${select.getAttribute( - "data-setting-select-default" - )}]` - ); - - this.setDisabledDefault(btnCustom, defaultMethod); - }); - } - - setDisabledDefault(inp, method) { - if (method === "ui" || method === "default") { - inp.removeAttribute("disabled"); - } else { - inp.setAttribute("disabled", ""); - } - } - - setForm(action, serviceName, formEl) { - this.modalTitle.textContent = `${action} ${serviceName}`; - formEl.setAttribute("id", `form-${action}-${serviceName}`); - const opeInp = formEl.querySelector(`input[name="operation"]`); - opeInp.setAttribute("value", action); - opeInp.value = action; - - if (action === "edit" || action === "new") { - this.showNewEditForm(); - const oldNameInp = formEl.querySelector(`input[name="OLD_SERVER_NAME"]`); - oldNameInp.setAttribute("value", serviceName); - oldNameInp.value = serviceName; - } - - if (action === "delete") { - this.showDeleteForm(); - formEl.querySelector( - `[data-services-modal-text]` - ).textContent = `Are you sure you want to delete ${serviceName} ?`; - const nameInp = formEl.querySelector(`input[name="SERVER_NAME"]`); - nameInp.setAttribute("value", serviceName); - nameInp.value = serviceName; - } - } - - showNewEditForm() { - this.cardViewport(); - this.showTabs(); - this.hideForms(); - this.formNewEdit.classList.remove("hidden"); - } - - showDeleteForm() { - this.cardNoViewport(); - this.hideTabs(); - this.hideForms(); - - this.formDelete.classList.remove("hidden"); - } - - cardViewport() { - this.modalCard.classList.add("h-[90vh]"); - this.modalCard.classList.add("w-full"); - } - - cardNoViewport() { - this.modalCard.classList.remove("h-[90vh]"); - this.modalCard.classList.remove("w-full"); - } - - hideForms() { - this.formNewEdit.classList.add("hidden"); - this.formDelete.classList.add("hidden"); - } - - hideTabs() { - this.modalTabs.classList.remove("grid"); - this.modalTabs.classList.add("hidden"); - - this.modalTabsHeader.classList.remove("flex"); - this.modalTabsHeader.classList.add("hidden"); - } - - showTabs() { - this.modalTabs.classList.add("grid"); - this.modalTabs.classList.remove("hidden"); - this.modalTabsHeader.classList.add("flex"); - this.modalTabsHeader.classList.remove("hidden"); - } - - updateModalData(settings) { - //use this to select inputEl and change value - for (const [key, data] of Object.entries(settings)) { - //change format to match id - const value = data["value"]; - const method = data["method"]; - const global = data["global"]; - try { - const inps = this.modal.querySelectorAll(`[name='${key}']`); - - inps.forEach((inp) => { - //form related values are excludes - const inpName = inp.getAttribute("name"); - if ( - inpName === "csrf_token" || - inpName === "OLD_SERVER_NAME" || - inpName === "operation" || - inpName === "settings-filter" - ) - return; - - //SET DISABLED / ENABLED - //for regular input - if ( - inp.tagName === "INPUT" && - inp.getAttribute("type") !== "checkbox" - ) { - inp.setAttribute("value", value); - inp.value = value; - inp.setAttribute("data-method", method); - } - //for checkbox - if ( - inp.tagName === "INPUT" && - inp.getAttribute("type") === "checkbox" - ) { - value === "yes" - ? inp.setAttribute("aria-checked", "true") - : inp.setAttribute("aria-checked", "false"); - inp.setAttribute("value", value); - inp.setAttribute("data-method", method); - inp.checked = true; - } - //for select - if (inp.tagName === "SELECT") { - inp.parentElement - .querySelector( - `button[data-setting-select-dropdown-btn][value='${value}']` - ) - .click(); - inp.setAttribute("data-method", method); - } - - //check disabled/enabled after setting values and methods - this.setDisabledServ(inp, method, global); - }); - } catch (err) {} - } - } - - setDisabledServ(inp, method, global) { - if (global) return inp.removeAttribute("disabled"); - - if (method === "ui" || method === "default") { - inp.removeAttribute("disabled"); - } else { - inp.setAttribute("disabled", ""); - } - } - - //UTILS - toggleModal() { - this.modal.classList.toggle("hidden"); - this.modal.classList.toggle("flex"); - } - - closeModal() { - this.modal.classList.add("hidden"); - this.modal.classList.remove("flex"); - } - - openModal() { - //switch to first setting - document.querySelector("button[data-tab-handler]").click(); - //show modal el - this.modal.classList.add("flex"); - this.modal.classList.remove("hidden"); - } -} - -class Multiple { - constructor(prefix) { - this.prefix = prefix; - this.container = document.querySelector("main"); - this.modalForm = document.querySelector(`[data-${this.prefix}-modal-form]`); - this.init(); - } - - init() { - window.addEventListener("load", () => { - this.hiddenIfNoMultiples(); - }); - - this.container.addEventListener("click", (e) => { - //edit service button - try { - if ( - e.target.closest("button").getAttribute("data-services-action") === - "edit" - ) { - //remove all multiples - this.removePrevMultiples(); - //get multiple service values and parse as obj - const servicesSettings = e.target - .closest("[data-services-service]") - .querySelector("[data-services-settings]") - .getAttribute("data-value"); - const obj = JSON.parse(servicesSettings); - //keep only multiple settings value - const multipleSettings = this.getMultiplesOnly(obj); - const sortMultiples = - this.sortMultipleByContainerAndSuffixe(multipleSettings); - this.setMultipleToDOM(sortMultiples); - } - } catch (err) {} - //new service button - try { - if ( - e.target.closest("button").getAttribute("data-services-action") === - "new" - ) { - this.removePrevMultiples(); - this.addOneMultGroup(); - } - } catch (err) {} - }); - - this.modalForm.addEventListener("click", (e) => { - //ADD BTN - try { - if ( - e.target - .closest("button") - .hasAttribute(`data-${this.prefix}-multiple-add`) - ) { - //get plugin from btn - const btn = e.target.closest("button"); - const attName = btn.getAttribute(`data-${this.prefix}-multiple-add`); - //get all multiple groups - const multipleEls = document.querySelectorAll( - `[data-${this.prefix}-settings-multiple*="${attName}"]` - ); - //case no schema - if (multipleEls.length <= 0) return; - - //get the next container number logic - //default is 0 - let topNum = 0; - //loop on curr multiples, get the name suffix for each - //and keep the highest num - multipleEls.forEach((container) => { - const ctnrName = container.getAttribute( - "data-services-settings-multiple" - ); - const num = this.getSuffixNumOrFalse(ctnrName); - if (!isNaN(num) && num > topNum) topNum = num; - }); - //the final number is num - //num is total - 1 because of hidden SCHEMA container - const currNum = `${multipleEls.length >= 2 ? topNum + 1 : topNum}`; - const setNum = +currNum === 0 ? `` : `_${currNum}`; - //the default (schema) group is the last group - const schema = document.querySelector( - `[data-${this.prefix}-settings-multiple="${attName}_SCHEMA"]` - ); - //clone schema to create a group with new num - const schemaClone = schema.cloneNode(true); - //add special attribut for disabled logic - this.changeCloneSuffix(schemaClone, setNum); - //set disabled / enabled state - this.setDisabledMultNew(schemaClone); - this.showClone(schema, schemaClone); - //insert new group before first one - //show all groups - this.showMultByAtt(attName); - } - } catch (err) {} - - //TOGGLE BTN - try { - if ( - e.target - .closest("button") - .hasAttribute(`data-${this.prefix}-multiple-toggle`) - ) { - const att = e.target - .closest("button") - .getAttribute(`data-${this.prefix}-multiple-toggle`); - this.toggleMultByAtt(att); - } - //remove last child - } catch (err) {} - - //REMOVE BTN - try { - if ( - e.target - .closest("button") - .hasAttribute(`data-${this.prefix}-multiple-delete`) - ) { - const multContainer = e.target.closest( - "[data-services-settings-multiple]" - ); - multContainer.remove(); - } - //remove last child - } catch (err) {} - }); - } - - sortMultipleByContainerAndSuffixe(obj) { - const sortMultiples = {}; - for (const [name, value] of Object.entries(obj)) { - //split name and check if there is a suffixe - const splitName = name.split("_"); - //suffixe start with number 1, if none give arbitrary 0 value to store on same group - const isSuffixe = !isNaN(splitName[splitName.length - 1]) ? true : false; - const suffixe = isSuffixe ? splitName[splitName.length - 1] : "0"; - //remove suffix if exists and query related name_SCHEMA to get container info - const nameSuffixLess = isSuffixe - ? name.replace(`_${splitName[splitName.length - 1]}`, "").trim() - : name.trim(); - const relateSetting = document.querySelector( - `[data-setting-container=${nameSuffixLess}_SCHEMA]` - ); - const relateCtnr = relateSetting.closest( - "[data-services-settings-multiple]" - ); - const relateCtnrName = relateCtnr.getAttribute( - "data-services-settings-multiple" - ); - //then we sort the setting on the right container name by suffixe number - if (!(relateCtnrName in sortMultiples)) { - sortMultiples[relateCtnrName] = {}; - } - - if (!(suffixe in sortMultiples[relateCtnrName])) { - sortMultiples[relateCtnrName][suffixe] = {}; - } - sortMultiples[relateCtnrName][suffixe][name] = value; - } - return sortMultiples; - } - - addOneMultGroup() { - const settings = document.querySelector("[data-services-modal-form]"); - const multAddBtns = settings.querySelectorAll( - "[data-services-multiple-add]" - ); - multAddBtns.forEach((btn) => { - //check if already one (SCHEMA exclude so length >= 2) - const plugin = btn.closest("[data-plugin-item]"); - if ( - plugin.querySelectorAll("[data-services-settings-multiple]").length >= 2 - ) - return; - btn.click(); - }); - } - - showMultByAtt(att) { - const multContainers = document.querySelectorAll( - `[data-services-settings-multiple^=${att}]` - ); - multContainers.forEach((container) => { - if ( - !container - .getAttribute("data-services-settings-multiple") - .includes("SCHEMA") - ) - container.classList.remove("hidden"); - }); - } - - toggleMultByAtt(att) { - const multContainers = document.querySelectorAll( - `[data-services-settings-multiple^=${att}]` - ); - multContainers.forEach((container) => { - if ( - !container - .getAttribute("data-services-settings-multiple") - .includes("SCHEMA") - ) - container.classList.toggle("hidden"); - }); - } - - getMultiplesOnly(settings) { - //get schema settings - const multiples = {}; - const schemaSettings = document.querySelectorAll( - `[data-setting-container$="SCHEMA"]` - ); - // loop on every schema settings - schemaSettings.forEach((schema) => { - const schemaName = schema - .getAttribute("data-setting-container") - .replace("_SCHEMA", "") - .trim(); - //check if match with service setting - for (const [key, data] of Object.entries(settings)) { - if (key.includes(schemaName)) { - multiples[key] = { - value: data["value"], - method: data["method"], - global: data["global"], - }; - } - } - }); - return multiples; - } - - //put multiple on the right plugin, on schema container - setMultipleToDOM(sortMultObj) { - //we loop on each multiple that contains values to render to DOM - for (const [schemaCtnrName, multGroupBySuffix] of Object.entries( - sortMultObj - )) { - //we need to access the DOM schema container - const schemaCtnr = document.querySelector( - `[data-services-settings-multiple="${schemaCtnrName}"]` - ); - //now we have to loop on each multiple settings group - for (const [suffix, settings] of Object.entries(multGroupBySuffix)) { - //we have to clone schema container first - const schemaCtnrClone = schemaCtnr.cloneNode(true); - //remove id to avoid duplicate and for W3C - schemaCtnr.removeAttribute("id"); - //now we replace _SCHEMA by current suffix everywhere we need - //unless it is 0 that means no suffix - const suffixFormat = +suffix === 0 ? `` : `_${suffix}`; - this.changeCloneSuffix(schemaCtnrClone, suffixFormat); - //then we have to loop on every settings of current group to change clone values by right ones - for (const [name, data] of Object.entries(settings)) { - //get setting container of clone container - const settingContainer = schemaCtnrClone.querySelector( - `[data-setting-container="${name}"]` - ); - //replace input info and disabled state - this.setSetting( - data["value"], - data["method"], - data["global"], - settingContainer - ); - } - //send schema clone to DOM and show it - this.showClone(schemaCtnr, schemaCtnrClone); - } - } - } - - changeCloneSuffix(schemaCtnrClone, suffix) { - //rename multiple container - schemaCtnrClone.setAttribute( - "data-services-settings-multiple", - schemaCtnrClone - .getAttribute("data-services-settings-multiple") - .replace("_SCHEMA", suffix) - ); - - //rename title - const titles = schemaCtnrClone.querySelectorAll("h5"); - titles.forEach((title) => { - const text = title.textContent; - title.textContent = `${text} ${ - suffix ? `#${suffix.replace("_", "")}` : `` - }`; - }); - - //rename setting container - const settingCtnrs = schemaCtnrClone.querySelectorAll( - "[data-setting-container]" - ); - settingCtnrs.forEach((settingCtnr) => { - settingCtnr.setAttribute( - "data-setting-container", - settingCtnr - .getAttribute("data-setting-container") - .replace("_SCHEMA", suffix) - ); - settingCtnr.setAttribute( - "id", - settingCtnr.getAttribute("id").replace("_SCHEMA", suffix) - ); - }); - - //rename input - try { - const inps = schemaCtnrClone.querySelectorAll("input"); - this.renameLoop(inps, suffix); - } catch (err) {} - - //rename select - try { - const selects = schemaCtnrClone.querySelectorAll("select"); - this.renameLoop(selects, suffix); - } catch (err) {} - } - - renameLoop(inps, suffix) { - inps.forEach((inp) => { - const newName = inp.getAttribute("name").replace("_SCHEMA", suffix); - inp.setAttribute("name", newName); - if (inp.hasAttribute("id")) inp.setAttribute("id", newName); - }); - } - - setSetting(value, method, global, settingContainer) { - //update input - try { - const inps = settingContainer.querySelectorAll("input"); - inps.forEach((inp) => { - //form related values are excludes - const inpName = inp.getAttribute("name"); - if ( - inpName === "csrf_token" || - inpName === "OLD_SERVER_NAME" || - inpName === "operation" || - inpName === "settings-filter" - ) - return; - - //for settings input - if (inp.getAttribute("type") === "checkbox") { - value === "yes" - ? inp.setAttribute("aria-checked", "true") - : inp.setAttribute("aria-checked", "false"); - inp.setAttribute("value", value); - inp.setAttribute("data-method", method); - inp.checked = true; - } - - if (inp.getAttribute("type") !== "checkbox") { - inp.setAttribute("value", value); - inp.value = value; - inp.setAttribute("data-method", method); - } - this.setDisabledMultServ(inp, method, global); - }); - } catch (err) {} - //update select - try { - const select = settingContainer.querySelector("select"); - select.setAttribute("data-method", method); - - //click the custom select dropdown btn vavlue to update select value - select.parentElement - .querySelector( - `button[data-setting-select-dropdown-btn][value='${defaultVal}']` - ) - .click(); - - //set state to custom visible el - const btnCustom = document.querySelector( - `[data-setting-select=${select.getAttribute( - "data-setting-select-default" - )}]` - ); - - this.setDisabledMultServ(btnCustom, method, global); - } catch (err) {} - } - - showClone(schemaCtnr, schemaCtnrClone) { - schemaCtnr.insertAdjacentElement("afterend", schemaCtnrClone); - schemaCtnrClone.classList.remove("hidden"); - schemaCtnrClone.classList.add("grid"); - } - - //global value isn't check at this point - setDisabledMultNew(container) { - const settings = container.querySelectorAll("[data-setting-container]"); - - settings.forEach((setting) => { - //replace input info - try { - const inps = setting.querySelectorAll("input"); - inps.forEach((inp) => { - const method = inp.getAttribute("data-default-method"); - if (method === "ui" || method === "default") { - inp.removeAttribute("disabled"); - } else { - inp.setAttribute("disabled", ""); - } - }); - } catch (err) {} - //or select - try { - const selects = setting.querySelectorAll("select"); - selects.forEach((select) => { - const method = select.getAttribute("data-default-method"); - const name = select.getAttribute( - "data-services-setting-select-default" - ); - const selDOM = document.querySelector( - `button[data-services-setting-select='${name}']` - ); - if (method === "ui" || method === "default") { - selDOM.removeAttribute("disabled", ""); - } else { - selDOM.setAttribute("disabled", ""); - } - }); - } catch (err) {} - }); - } - - //for already existing services multiples - //global is check - setDisabledMultServ(inp, method, global) { - if (global) return inp.removeAttribute("disabled"); - - if (method === "ui" || method === "default") { - inp.removeAttribute("disabled"); - } else { - inp.setAttribute("disabled", ""); - } - } - //UTILS - - getSuffixNumOrFalse(name) { - const num = !isNaN(Number(name.substring(name.lastIndexOf("_") + 1))) - ? Number(name.substring(name.lastIndexOf("_") + 1)) - : ""; - return num; - } - - hiddenIfNoMultiples() { - //hide multiple btn if no multiple exist on a plugin - const multiples = document.querySelectorAll( - `[data-${this.prefix}-settings-multiple]` - ); - multiples.forEach((container) => { - if (container.querySelectorAll(`[data-setting-container]`).length <= 0) - container.parentElement - .querySelector("[data-multiple-handler]") - .classList.add("hidden"); - }); - } - - removePrevMultiples() { - const multiPlugins = document.querySelectorAll( - `[data-${this.prefix}-settings-multiple]` - ); - multiPlugins.forEach((multiGrp) => { - if ( - !multiGrp - .getAttribute("data-services-settings-multiple") - .includes("SCHEMA") - ) - multiGrp.remove(); - }); - } - - showMultiple(el) { - el.classList.add("grid"); - el.classList.remove("hidden"); - } - - setNameIDloop(iterable, value) { - iterable.forEach((item) => { - const currID = item.getAttribute("id"); - const currName = item.getAttribute("name"); - item.setAttribute("id", `${currID}_${value}`); - item.setAttribute("name", `${currName}_${value}`); - }); - } - - setNameID(el, value) { - el.setAttribute("id", `${value}`); - el.setAttribute("name", `${value}`); - } -} - -const setPopover = new Popover(); -const setTabs = new Tabs(); -const setModal = new ServiceModal(); -const format = new FormatValue(); -const setFilterGlobal = new FilterSettings( - "settings-filter", - "[data-service-content='settings']" -); - -const setMultiple = new Multiple("services"); +import { + Popover, + Tabs, + FormatValue, + FilterSettings, +} from "./utils/settings.js"; + +class ServiceModal { + constructor() { + //modal elements + this.modal = document.querySelector("[data-services-modal]"); + this.modalTitle = this.modal.querySelector("[data-services-modal-title]"); + this.modalTabs = this.modal.querySelector(["[data-services-tabs]"]); + this.modalTabsHeader = this.modal.querySelector([ + "[data-services-tabs-header]", + ]); + + this.modalCard = this.modal.querySelector("[data-services-modal-card]"); + //modal forms + this.formNewEdit = this.modal.querySelector("[data-services-modal-form]"); + this.formDelete = this.modal.querySelector( + "[data-services-modal-form-delete]", + ); + this.submitBtn = document.querySelector( + "button[data-services-modal-submit]", + ); + //container + this.container = document.querySelector("main"); + this.init(); + } + + //store default config data on DOM + //to update modal data on new button click + + getActionAndServName(target) { + const action = target + .closest("button") + .getAttribute("data-services-action"); + const serviceName = target + .closest("button") + .getAttribute("data-services-name"); + + return [action, serviceName]; + } + + init() { + this.modal.addEventListener("click", (e) => { + //close + try { + if ( + e.target.closest("button").hasAttribute("data-services-modal-close") + ) { + this.closeModal(); + } + } catch (err) {} + }); + + this.container.addEventListener("click", (e) => { + //edit action + try { + if ( + e.target.closest("button").getAttribute("data-services-action") === + "edit" + ) { + //set form info and right form + const [action, serviceName] = this.getActionAndServName(e.target); + this.setForm(action, serviceName, this.formNewEdit); + //get service data and parse it + //multiple type logic is launch at same time on relate class + const servicesSettings = e.target + .closest("[data-services-service]") + .querySelector("[data-services-settings]") + .getAttribute("data-value"); + const obj = JSON.parse(servicesSettings); + this.updateModalData(obj); + //show modal + this.resetFilterInp(); + this.changeSubmitBtn("EDIT", "edit-btn"); + this.openModal(); + } + } catch (err) {} + //new action + try { + if ( + e.target.closest("button").getAttribute("data-services-action") === + "new" + ) { + //set form info and right form + const [action, serviceName] = this.getActionAndServName(e.target); + this.setForm(action, serviceName, this.formNewEdit); + //set default value with method default + this.setSettingsDefault(); + //server name is unset + const inpServName = document.querySelector("input#SERVER_NAME"); + inpServName.getAttribute("value", ""); + inpServName.removeAttribute("disabled", ""); + inpServName.value = ""; + + //show modal + this.resetFilterInp(); + this.changeSubmitBtn("CREATE", "valid-btn"); + this.openModal(); + } + } catch (err) {} + //delete action + try { + if ( + e.target.closest("button").getAttribute("data-services-action") === + "delete" + ) { + //set form info and right form + const [action, serviceName] = this.getActionAndServName(e.target); + this.setForm(action, serviceName, this.formDelete); + //show modal + this.openModal(); + } + } catch (err) {} + }); + } + + resetFilterInp() { + const inpFilter = document.querySelector('input[name="settings-filter"]'); + inpFilter.value = ""; + inpFilter.dispatchEvent(new Event("input")); + } + + changeSubmitBtn(text, btnType) { + this.submitBtn.textContent = text; + this.submitBtn.classList.remove( + "delete-btn", + "valid-btn", + "edit-btn", + "info-btn", + ); + this.submitBtn.classList.add(btnType); + } + + setSettingsDefault() { + const inps = this.modal.querySelectorAll("input"); + inps.forEach((inp) => { + //form related values are excludes + const inpName = inp.getAttribute("name"); + if ( + inpName === "csrf_token" || + inpName === "OLD_SERVER_NAME" || + inpName === "operation" || + inpName === "settings-filter" + ) + return; + + //for all other settings values + const defaultMethod = inp.getAttribute("data-default-method"); + const defaultVal = inp.getAttribute("data-default-value"); + + //SET VALUE + if (inp.getAttribute("type") === "checkbox") { + defaultVal === "yes" + ? inp.setAttribute("aria-checked", "true") + : inp.setAttribute("aria-checked", "false"); + inp.setAttribute("value", defaultVal); + inp.setAttribute("data-method", defaultMethod); + inp.checked = true; + } + + if (inp.getAttribute("type") !== "checkbox") { + inp.setAttribute("value", defaultVal); + inp.value = defaultVal; + inp.setAttribute("data-method", defaultMethod); + } + + //SET METHOD + this.setDisabledDefault(inp, defaultMethod); + }); + + const selects = this.modal.querySelectorAll("select"); + selects.forEach((select) => { + const defaultMethod = select.getAttribute("data-default-method"); + const defaultVal = select.getAttribute("data-default-value"); + //click the custom select dropdown to update select value + select.parentElement + .querySelector( + `button[data-setting-select-dropdown-btn][value='${defaultVal}']`, + ) + .click(); + + //set state to custom visible el + const btnCustom = document.querySelector( + `[data-setting-select=${select.getAttribute( + "data-setting-select-default", + )}]`, + ); + + this.setDisabledDefault(btnCustom, defaultMethod); + }); + } + + setDisabledDefault(inp, method) { + if (method === "ui" || method === "default") { + inp.removeAttribute("disabled"); + } else { + inp.setAttribute("disabled", ""); + } + } + + setForm(action, serviceName, formEl) { + this.modalTitle.textContent = `${action} ${serviceName}`; + formEl.setAttribute("id", `form-${action}-${serviceName}`); + const opeInp = formEl.querySelector(`input[name="operation"]`); + opeInp.setAttribute("value", action); + opeInp.value = action; + + if (action === "edit" || action === "new") { + this.showNewEditForm(); + const oldNameInp = formEl.querySelector(`input[name="OLD_SERVER_NAME"]`); + oldNameInp.setAttribute("value", serviceName); + oldNameInp.value = serviceName; + } + + if (action === "delete") { + this.showDeleteForm(); + formEl.querySelector( + `[data-services-modal-text]`, + ).textContent = `Are you sure you want to delete ${serviceName} ?`; + const nameInp = formEl.querySelector(`input[name="SERVER_NAME"]`); + nameInp.setAttribute("value", serviceName); + nameInp.value = serviceName; + } + } + + showNewEditForm() { + this.cardViewport(); + this.showTabs(); + this.hideForms(); + this.formNewEdit.classList.remove("hidden"); + } + + showDeleteForm() { + this.cardNoViewport(); + this.hideTabs(); + this.hideForms(); + + this.formDelete.classList.remove("hidden"); + } + + cardViewport() { + this.modalCard.classList.add("h-[90vh]"); + this.modalCard.classList.add("w-full"); + } + + cardNoViewport() { + this.modalCard.classList.remove("h-[90vh]"); + this.modalCard.classList.remove("w-full"); + } + + hideForms() { + this.formNewEdit.classList.add("hidden"); + this.formDelete.classList.add("hidden"); + } + + hideTabs() { + this.modalTabs.classList.remove("grid"); + this.modalTabs.classList.add("hidden"); + + this.modalTabsHeader.classList.remove("flex"); + this.modalTabsHeader.classList.add("hidden"); + } + + showTabs() { + this.modalTabs.classList.add("grid"); + this.modalTabs.classList.remove("hidden"); + this.modalTabsHeader.classList.add("flex"); + this.modalTabsHeader.classList.remove("hidden"); + } + + updateModalData(settings) { + //use this to select inputEl and change value + for (const [key, data] of Object.entries(settings)) { + //change format to match id + const value = data["value"]; + const method = data["method"]; + const global = data["global"]; + try { + const inps = this.modal.querySelectorAll(`[name='${key}']`); + + inps.forEach((inp) => { + //form related values are excludes + const inpName = inp.getAttribute("name"); + if ( + inpName === "csrf_token" || + inpName === "OLD_SERVER_NAME" || + inpName === "operation" || + inpName === "settings-filter" + ) + return; + + //SET DISABLED / ENABLED + //for regular input + if ( + inp.tagName === "INPUT" && + inp.getAttribute("type") !== "checkbox" + ) { + inp.setAttribute("value", value); + inp.value = value; + inp.setAttribute("data-method", method); + } + //for checkbox + if ( + inp.tagName === "INPUT" && + inp.getAttribute("type") === "checkbox" + ) { + value === "yes" + ? inp.setAttribute("aria-checked", "true") + : inp.setAttribute("aria-checked", "false"); + inp.setAttribute("value", value); + inp.setAttribute("data-method", method); + inp.checked = true; + } + //for select + if (inp.tagName === "SELECT") { + inp.parentElement + .querySelector( + `button[data-setting-select-dropdown-btn][value='${value}']`, + ) + .click(); + inp.setAttribute("data-method", method); + } + + //check disabled/enabled after setting values and methods + this.setDisabledServ(inp, method, global); + }); + } catch (err) {} + } + } + + setDisabledServ(inp, method, global) { + if (global) return inp.removeAttribute("disabled"); + + if (method === "ui" || method === "default") { + inp.removeAttribute("disabled"); + } else { + inp.setAttribute("disabled", ""); + } + } + + //UTILS + toggleModal() { + this.modal.classList.toggle("hidden"); + this.modal.classList.toggle("flex"); + } + + closeModal() { + this.modal.classList.add("hidden"); + this.modal.classList.remove("flex"); + } + + openModal() { + //switch to first setting + document.querySelector("button[data-tab-handler]").click(); + //show modal el + this.modal.classList.add("flex"); + this.modal.classList.remove("hidden"); + } +} + +class Multiple { + constructor(prefix) { + this.prefix = prefix; + this.container = document.querySelector("main"); + this.modalForm = document.querySelector(`[data-${this.prefix}-modal-form]`); + this.init(); + } + + init() { + window.addEventListener("load", () => { + this.hiddenIfNoMultiples(); + }); + + this.container.addEventListener("click", (e) => { + //edit service button + try { + if ( + e.target.closest("button").getAttribute("data-services-action") === + "edit" + ) { + //remove all multiples + this.removePrevMultiples(); + //get multiple service values and parse as obj + const servicesSettings = e.target + .closest("[data-services-service]") + .querySelector("[data-services-settings]") + .getAttribute("data-value"); + const obj = JSON.parse(servicesSettings); + //keep only multiple settings value + const multipleSettings = this.getMultiplesOnly(obj); + const sortMultiples = + this.sortMultipleByContainerAndSuffixe(multipleSettings); + this.setMultipleToDOM(sortMultiples); + } + } catch (err) {} + //new service button + try { + if ( + e.target.closest("button").getAttribute("data-services-action") === + "new" + ) { + this.removePrevMultiples(); + this.addOneMultGroup(); + } + } catch (err) {} + }); + + this.modalForm.addEventListener("click", (e) => { + //ADD BTN + try { + if ( + e.target + .closest("button") + .hasAttribute(`data-${this.prefix}-multiple-add`) + ) { + //get plugin from btn + const btn = e.target.closest("button"); + const attName = btn.getAttribute(`data-${this.prefix}-multiple-add`); + //get all multiple groups + const multipleEls = document.querySelectorAll( + `[data-${this.prefix}-settings-multiple*="${attName}"]`, + ); + //case no schema + if (multipleEls.length <= 0) return; + + //get the next container number logic + //default is 0 + let topNum = 0; + //loop on curr multiples, get the name suffix for each + //and keep the highest num + multipleEls.forEach((container) => { + const ctnrName = container.getAttribute( + "data-services-settings-multiple", + ); + const num = this.getSuffixNumOrFalse(ctnrName); + if (!isNaN(num) && num > topNum) topNum = num; + }); + //the final number is num + //num is total - 1 because of hidden SCHEMA container + const currNum = `${multipleEls.length >= 2 ? topNum + 1 : topNum}`; + const setNum = +currNum === 0 ? `` : `_${currNum}`; + //the default (schema) group is the last group + const schema = document.querySelector( + `[data-${this.prefix}-settings-multiple="${attName}_SCHEMA"]`, + ); + //clone schema to create a group with new num + const schemaClone = schema.cloneNode(true); + //add special attribut for disabled logic + this.changeCloneSuffix(schemaClone, setNum); + //set disabled / enabled state + this.setDisabledMultNew(schemaClone); + this.showClone(schema, schemaClone); + //insert new group before first one + //show all groups + this.showMultByAtt(attName); + } + } catch (err) {} + + //TOGGLE BTN + try { + if ( + e.target + .closest("button") + .hasAttribute(`data-${this.prefix}-multiple-toggle`) + ) { + const att = e.target + .closest("button") + .getAttribute(`data-${this.prefix}-multiple-toggle`); + this.toggleMultByAtt(att); + } + //remove last child + } catch (err) {} + + //REMOVE BTN + try { + if ( + e.target + .closest("button") + .hasAttribute(`data-${this.prefix}-multiple-delete`) + ) { + const multContainer = e.target.closest( + "[data-services-settings-multiple]", + ); + multContainer.remove(); + } + //remove last child + } catch (err) {} + }); + } + + sortMultipleByContainerAndSuffixe(obj) { + const sortMultiples = {}; + for (const [name, value] of Object.entries(obj)) { + //split name and check if there is a suffixe + const splitName = name.split("_"); + //suffixe start with number 1, if none give arbitrary 0 value to store on same group + const isSuffixe = !isNaN(splitName[splitName.length - 1]) ? true : false; + const suffixe = isSuffixe ? splitName[splitName.length - 1] : "0"; + //remove suffix if exists and query related name_SCHEMA to get container info + const nameSuffixLess = isSuffixe + ? name.replace(`_${splitName[splitName.length - 1]}`, "").trim() + : name.trim(); + const relateSetting = document.querySelector( + `[data-setting-container=${nameSuffixLess}_SCHEMA]`, + ); + const relateCtnr = relateSetting.closest( + "[data-services-settings-multiple]", + ); + const relateCtnrName = relateCtnr.getAttribute( + "data-services-settings-multiple", + ); + //then we sort the setting on the right container name by suffixe number + if (!(relateCtnrName in sortMultiples)) { + sortMultiples[relateCtnrName] = {}; + } + + if (!(suffixe in sortMultiples[relateCtnrName])) { + sortMultiples[relateCtnrName][suffixe] = {}; + } + sortMultiples[relateCtnrName][suffixe][name] = value; + } + return sortMultiples; + } + + addOneMultGroup() { + const settings = document.querySelector("[data-services-modal-form]"); + const multAddBtns = settings.querySelectorAll( + "[data-services-multiple-add]", + ); + multAddBtns.forEach((btn) => { + //check if already one (SCHEMA exclude so length >= 2) + const plugin = btn.closest("[data-plugin-item]"); + if ( + plugin.querySelectorAll("[data-services-settings-multiple]").length >= 2 + ) + return; + btn.click(); + }); + } + + showMultByAtt(att) { + const multContainers = document.querySelectorAll( + `[data-services-settings-multiple^=${att}]`, + ); + multContainers.forEach((container) => { + if ( + !container + .getAttribute("data-services-settings-multiple") + .includes("SCHEMA") + ) + container.classList.remove("hidden"); + }); + } + + toggleMultByAtt(att) { + const multContainers = document.querySelectorAll( + `[data-services-settings-multiple^=${att}]`, + ); + multContainers.forEach((container) => { + if ( + !container + .getAttribute("data-services-settings-multiple") + .includes("SCHEMA") + ) + container.classList.toggle("hidden"); + }); + } + + getMultiplesOnly(settings) { + //get schema settings + const multiples = {}; + const schemaSettings = document.querySelectorAll( + `[data-setting-container$="SCHEMA"]`, + ); + // loop on every schema settings + schemaSettings.forEach((schema) => { + const schemaName = schema + .getAttribute("data-setting-container") + .replace("_SCHEMA", "") + .trim(); + //check if match with service setting + for (const [key, data] of Object.entries(settings)) { + if (key.includes(schemaName)) { + multiples[key] = { + value: data["value"], + method: data["method"], + global: data["global"], + }; + } + } + }); + return multiples; + } + + //put multiple on the right plugin, on schema container + setMultipleToDOM(sortMultObj) { + //we loop on each multiple that contains values to render to DOM + for (const [schemaCtnrName, multGroupBySuffix] of Object.entries( + sortMultObj, + )) { + //we need to access the DOM schema container + const schemaCtnr = document.querySelector( + `[data-services-settings-multiple="${schemaCtnrName}"]`, + ); + //now we have to loop on each multiple settings group + for (const [suffix, settings] of Object.entries(multGroupBySuffix)) { + //we have to clone schema container first + const schemaCtnrClone = schemaCtnr.cloneNode(true); + //remove id to avoid duplicate and for W3C + schemaCtnr.removeAttribute("id"); + //now we replace _SCHEMA by current suffix everywhere we need + //unless it is 0 that means no suffix + const suffixFormat = +suffix === 0 ? `` : `_${suffix}`; + this.changeCloneSuffix(schemaCtnrClone, suffixFormat); + //then we have to loop on every settings of current group to change clone values by right ones + for (const [name, data] of Object.entries(settings)) { + //get setting container of clone container + const settingContainer = schemaCtnrClone.querySelector( + `[data-setting-container="${name}"]`, + ); + //replace input info and disabled state + this.setSetting( + data["value"], + data["method"], + data["global"], + settingContainer, + ); + } + //send schema clone to DOM and show it + this.showClone(schemaCtnr, schemaCtnrClone); + } + } + } + + changeCloneSuffix(schemaCtnrClone, suffix) { + //rename multiple container + schemaCtnrClone.setAttribute( + "data-services-settings-multiple", + schemaCtnrClone + .getAttribute("data-services-settings-multiple") + .replace("_SCHEMA", suffix), + ); + + //rename title + const titles = schemaCtnrClone.querySelectorAll("h5"); + titles.forEach((title) => { + const text = title.textContent; + title.textContent = `${text} ${ + suffix ? `#${suffix.replace("_", "")}` : `` + }`; + }); + + //rename setting container + const settingCtnrs = schemaCtnrClone.querySelectorAll( + "[data-setting-container]", + ); + settingCtnrs.forEach((settingCtnr) => { + settingCtnr.setAttribute( + "data-setting-container", + settingCtnr + .getAttribute("data-setting-container") + .replace("_SCHEMA", suffix), + ); + settingCtnr.setAttribute( + "id", + settingCtnr.getAttribute("id").replace("_SCHEMA", suffix), + ); + }); + + //rename input + try { + const inps = schemaCtnrClone.querySelectorAll("input"); + this.renameLoop(inps, suffix); + } catch (err) {} + + //rename select + try { + const selects = schemaCtnrClone.querySelectorAll("select"); + this.renameLoop(selects, suffix); + } catch (err) {} + } + + renameLoop(inps, suffix) { + inps.forEach((inp) => { + const newName = inp.getAttribute("name").replace("_SCHEMA", suffix); + inp.setAttribute("name", newName); + if (inp.hasAttribute("id")) inp.setAttribute("id", newName); + }); + } + + setSetting(value, method, global, settingContainer) { + //update input + try { + const inps = settingContainer.querySelectorAll("input"); + inps.forEach((inp) => { + //form related values are excludes + const inpName = inp.getAttribute("name"); + if ( + inpName === "csrf_token" || + inpName === "OLD_SERVER_NAME" || + inpName === "operation" || + inpName === "settings-filter" + ) + return; + + //for settings input + if (inp.getAttribute("type") === "checkbox") { + value === "yes" + ? inp.setAttribute("aria-checked", "true") + : inp.setAttribute("aria-checked", "false"); + inp.setAttribute("value", value); + inp.setAttribute("data-method", method); + inp.checked = true; + } + + if (inp.getAttribute("type") !== "checkbox") { + inp.setAttribute("value", value); + inp.value = value; + inp.setAttribute("data-method", method); + } + this.setDisabledMultServ(inp, method, global); + }); + } catch (err) {} + //update select + try { + const select = settingContainer.querySelector("select"); + select.setAttribute("data-method", method); + + //click the custom select dropdown btn vavlue to update select value + select.parentElement + .querySelector( + `button[data-setting-select-dropdown-btn][value='${defaultVal}']`, + ) + .click(); + + //set state to custom visible el + const btnCustom = document.querySelector( + `[data-setting-select=${select.getAttribute( + "data-setting-select-default", + )}]`, + ); + + this.setDisabledMultServ(btnCustom, method, global); + } catch (err) {} + } + + showClone(schemaCtnr, schemaCtnrClone) { + schemaCtnr.insertAdjacentElement("afterend", schemaCtnrClone); + schemaCtnrClone.classList.remove("hidden"); + schemaCtnrClone.classList.add("grid"); + } + + //global value isn't check at this point + setDisabledMultNew(container) { + const settings = container.querySelectorAll("[data-setting-container]"); + + settings.forEach((setting) => { + //replace input info + try { + const inps = setting.querySelectorAll("input"); + inps.forEach((inp) => { + const method = inp.getAttribute("data-default-method"); + if (method === "ui" || method === "default") { + inp.removeAttribute("disabled"); + } else { + inp.setAttribute("disabled", ""); + } + }); + } catch (err) {} + //or select + try { + const selects = setting.querySelectorAll("select"); + selects.forEach((select) => { + const method = select.getAttribute("data-default-method"); + const name = select.getAttribute( + "data-services-setting-select-default", + ); + const selDOM = document.querySelector( + `button[data-services-setting-select='${name}']`, + ); + if (method === "ui" || method === "default") { + selDOM.removeAttribute("disabled", ""); + } else { + selDOM.setAttribute("disabled", ""); + } + }); + } catch (err) {} + }); + } + + //for already existing services multiples + //global is check + setDisabledMultServ(inp, method, global) { + if (global) return inp.removeAttribute("disabled"); + + if (method === "ui" || method === "default") { + inp.removeAttribute("disabled"); + } else { + inp.setAttribute("disabled", ""); + } + } + //UTILS + + getSuffixNumOrFalse(name) { + const num = !isNaN(Number(name.substring(name.lastIndexOf("_") + 1))) + ? Number(name.substring(name.lastIndexOf("_") + 1)) + : ""; + return num; + } + + hiddenIfNoMultiples() { + //hide multiple btn if no multiple exist on a plugin + const multiples = document.querySelectorAll( + `[data-${this.prefix}-settings-multiple]`, + ); + multiples.forEach((container) => { + if (container.querySelectorAll(`[data-setting-container]`).length <= 0) + container.parentElement + .querySelector("[data-multiple-handler]") + .classList.add("hidden"); + }); + } + + removePrevMultiples() { + const multiPlugins = document.querySelectorAll( + `[data-${this.prefix}-settings-multiple]`, + ); + multiPlugins.forEach((multiGrp) => { + if ( + !multiGrp + .getAttribute("data-services-settings-multiple") + .includes("SCHEMA") + ) + multiGrp.remove(); + }); + } + + showMultiple(el) { + el.classList.add("grid"); + el.classList.remove("hidden"); + } + + setNameIDloop(iterable, value) { + iterable.forEach((item) => { + const currID = item.getAttribute("id"); + const currName = item.getAttribute("name"); + item.setAttribute("id", `${currID}_${value}`); + item.setAttribute("name", `${currName}_${value}`); + }); + } + + setNameID(el, value) { + el.setAttribute("id", `${value}`); + el.setAttribute("name", `${value}`); + } +} + +const setPopover = new Popover(); +const setTabs = new Tabs(); +const setModal = new ServiceModal(); +const format = new FormatValue(); +const setFilterGlobal = new FilterSettings( + "settings-filter", + "[data-service-content='settings']", +); + +const setMultiple = new Multiple("services"); diff --git a/src/ui/static/js/tsparticles.bundle.min.js b/src/ui/static/js/tsparticles.bundle.min.js index ff59bac50..387fc09b7 100644 --- a/src/ui/static/js/tsparticles.bundle.min.js +++ b/src/ui/static/js/tsparticles.bundle.min.js @@ -1,2 +1,2 @@ -/*! tsParticles v2.0.6 by Matteo Bruni */ -!function(t,e){if("object"==typeof exports&&"object"==typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var i=e();for(var s in i)("object"==typeof exports?exports:t)[s]=i[s]}}(this,(()=>(()=>{"use strict";var t,e,i,s,o={},n={};function a(t){var e=n[t];if(void 0!==e)return e.exports;var i=n[t]={exports:{}};return o[t](i,i.exports,a),i.exports}a.m=o,e=Object.getPrototypeOf?t=>Object.getPrototypeOf(t):t=>t.__proto__,a.t=function(i,s){if(1&s&&(i=this(i)),8&s)return i;if("object"==typeof i&&i){if(4&s&&i.__esModule)return i;if(16&s&&"function"==typeof i.then)return i}var o=Object.create(null);a.r(o);var n={};t=t||[null,e({}),e([]),e(e)];for(var r=2&s&&i;"object"==typeof r&&!~t.indexOf(r);r=e(r))Object.getOwnPropertyNames(r).forEach((t=>n[t]=()=>i[t]));return n.default=()=>i,a.d(o,n),o},a.d=(t,e)=>{for(var i in e)a.o(e,i)&&!a.o(t,i)&&Object.defineProperty(t,i,{enumerable:!0,get:e[i]})},a.f={},a.e=t=>Promise.all(Object.keys(a.f).reduce(((e,i)=>(a.f[i](t,e),e)),[])),a.u=t=>t+".js",a.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(t){if("object"==typeof window)return window}}(),a.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),i={},s="tsparticles:",a.l=(t,e,o,n)=>{if(i[t])i[t].push(e);else{var r,l;if(void 0!==o)for(var c=document.getElementsByTagName("script"),d=0;d{r.onerror=r.onload=null,clearTimeout(p);var o=i[t];if(delete i[t],r.parentNode&&r.parentNode.removeChild(r),o&&o.forEach((t=>t(s))),e)return e(s)},p=setTimeout(u.bind(null,void 0,{type:"timeout",target:r}),12e4);r.onerror=u.bind(null,r.onerror),r.onload=u.bind(null,r.onload),l&&document.head.appendChild(r)}},a.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},(()=>{var t;a.g.importScripts&&(t=a.g.location+"");var e=a.g.document;if(!t&&e&&(e.currentScript&&(t=e.currentScript.src),!t)){var i=e.getElementsByTagName("script");i.length&&(t=i[i.length-1].src)}if(!t)throw new Error("Automatic publicPath is not supported in this browser");t=t.replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),a.p=t})(),(()=>{var t={420:0,870:0};a.f.j=(e,i)=>{var s=a.o(t,e)?t[e]:void 0;if(0!==s)if(s)i.push(s[2]);else{var o=new Promise(((i,o)=>s=t[e]=[i,o]));i.push(s[2]=o);var n=a.p+a.u(e),r=new Error;a.l(n,(i=>{if(a.o(t,e)&&(0!==(s=t[e])&&(t[e]=void 0),s)){var o=i&&("load"===i.type?"missing":i.type),n=i&&i.target&&i.target.src;r.message="Loading chunk "+e+" failed.\n("+o+": "+n+")",r.name="ChunkLoadError",r.type=o,r.request=n,s[1](r)}}),"chunk-"+e,e)}};var e=(e,i)=>{var s,o,[n,r,l]=i,c=0;if(n.some((e=>0!==t[e]))){for(s in r)a.o(r,s)&&(a.m[s]=r[s]);if(l)l(a)}for(e&&e(i);cMt,AnimatableGradient:()=>zt,AnimatableGradientColor:()=>Tt,AnimationOptions:()=>ie,Attract:()=>W,Background:()=>I,BackgroundMask:()=>L,BackgroundMaskCover:()=>D,Bounce:()=>j,Bubble:()=>$,BubbleBase:()=>G,BubbleDiv:()=>U,Canvas:()=>Zi,Circle:()=>vs,CircleWarp:()=>ys,ClickEvent:()=>q,Collisions:()=>Ht,CollisionsOverlap:()=>Rt,ColorAnimation:()=>kt,Connect:()=>X,ConnectLinks:()=>N,Container:()=>Cs,Destroy:()=>Bt,DivEvent:()=>F,Engine:()=>Fs,EventListeners:()=>ts,Events:()=>V,ExternalInteractorBase:()=>_s,FrameManager:()=>es,FullScreen:()=>H,Grab:()=>J,GrabLinks:()=>Y,GradientAngle:()=>Ct,GradientAngleAnimation:()=>St,GradientColorOpacity:()=>Et,GradientColorOpacityAnimation:()=>Ot,HoverEvent:()=>B,HslAnimation:()=>Pt,InteractionManager:()=>ns,Interactivity:()=>ct,Life:()=>jt,LifeDelay:()=>Vt,LifeDuration:()=>Wt,Light:()=>tt,LightArea:()=>Z,LightGradient:()=>Q,LightShadow:()=>K,Links:()=>$t,LinksShadow:()=>Gt,LinksTriangle:()=>Ut,Loader:()=>Os,Main:()=>Fs,ManualParticle:()=>dt,Modes:()=>lt,Motion:()=>ut,MotionReduce:()=>ht,Move:()=>ee,MoveAngle:()=>Nt,MoveAttract:()=>Xt,MoveGravity:()=>Yt,MovePath:()=>Qt,MovePathDelay:()=>Jt,MoveTrail:()=>Zt,Opacity:()=>oe,OpacityAnimation:()=>se,Options:()=>xt,OptionsColor:()=>A,Orbit:()=>ae,OrbitRotation:()=>ne,OutModes:()=>Kt,Parallax:()=>_,Particle:()=>hs,Particles:()=>xs,ParticlesBounce:()=>Lt,ParticlesBounceFactor:()=>Dt,ParticlesDensity:()=>re,ParticlesInteractorBase:()=>Bs,ParticlesNumber:()=>le,ParticlesOptions:()=>ze,ParticlesRepulse:()=>ce,Plugins:()=>Is,Point:()=>us,Push:()=>et,QuadTree:()=>ms,Range:()=>ps,Rectangle:()=>fs,Remove:()=>it,Repulse:()=>nt,RepulseBase:()=>st,RepulseDiv:()=>ot,Responsive:()=>pt,Retina:()=>ks,Roll:()=>he,RollLight:()=>de,Rotate:()=>pe,RotateAnimation:()=>ue,Shadow:()=>ve,Shape:()=>fe,Size:()=>me,SizeAnimation:()=>ye,Slow:()=>at,Spin:()=>te,Split:()=>_t,SplitFactor:()=>qt,SplitRate:()=>Ft,Stroke:()=>be,Theme:()=>ft,ThemeDefault:()=>vt,Tilt:()=>we,TiltAnimation:()=>ge,Trail:()=>rt,Twinkle:()=>ke,TwinkleValues:()=>xe,ValueWithRandom:()=>It,Vector:()=>u,Vector3d:()=>as,Wobble:()=>Pe,ZIndex:()=>Me,alterHsl:()=>Qi,animate:()=>Se,areBoundsInside:()=>He,arrayRandomIndex:()=>Ie,calcEasing:()=>C,calcExactPositionOrRandomFromSize:()=>O,calcExactPositionOrRandomFromSizeRanged:()=>R,calcPositionFromSize:()=>E,calcPositionOrRandomFromSize:()=>T,calcPositionOrRandomFromSizeRanged:()=>S,calculateBounds:()=>qe,cancelAnimation:()=>Oe,circleBounce:()=>Ge,circleBounceDataFromParticle:()=>je,clamp:()=>p,clear:()=>Vi,collisionVelocity:()=>z,colorMix:()=>Ai,colorToHsl:()=>vi,colorToRgb:()=>pi,deepExtend:()=>Fe,divMode:()=>We,divModeExecute:()=>Be,drawConnectLine:()=>Wi,drawEllipse:()=>Ji,drawGrabLine:()=>Gi,drawLine:()=>Fi,drawParticle:()=>Ui,drawParticlePlugin:()=>Yi,drawPlugin:()=>Xi,drawShape:()=>$i,drawShapeAfterEffect:()=>Ni,drawTriangle:()=>_i,generatedAttribute:()=>Ye,getDistance:()=>k,getDistances:()=>x,getHslAnimationFromHsl:()=>Hi,getHslFromAnimation:()=>Li,getLinkColor:()=>Ii,getLinkRandomColor:()=>Di,getParticleBaseVelocity:()=>M,getParticleDirectionAngle:()=>P,getRandomRgbColor:()=>Ti,getRangeMax:()=>b,getRangeMin:()=>m,getRangeValue:()=>y,getStyleFromHsl:()=>Oi,getStyleFromHsv:()=>Ri,getStyleFromRgb:()=>Si,getValue:()=>w,gradient:()=>ji,hslToHsv:()=>wi,hslToRgb:()=>bi,hslaToHsva:()=>xi,hslaToRgba:()=>gi,hsvToHsl:()=>ki,hsvToRgb:()=>Mi,hsvaToHsla:()=>Pi,hsvaToRgba:()=>zi,isDivModeEnabled:()=>_e,isInArray:()=>Re,isPointInside:()=>Le,isSsr:()=>Te,itemFromArray:()=>De,loadContainerOptions:()=>Ne,loadFont:()=>Ae,loadFull:()=>Gn,loadParticlesOptions:()=>Xe,loadSlim:()=>Bn,midColorValue:()=>Qe,mix:()=>v,mouseDownEvent:()=>Ke,mouseLeaveEvent:()=>oi,mouseMoveEvent:()=>ei,mouseOutEvent:()=>ni,mouseUpEvent:()=>ti,noPolygonDataLoaded:()=>ci,noPolygonFound:()=>di,paintBase:()=>Bi,randomColorValue:()=>Je,randomInRange:()=>f,rectBounce:()=>Ue,resizeEvent:()=>ri,rgbToHsl:()=>fi,rgbToHsv:()=>Ci,rgbaToHsva:()=>Ei,setRangeValue:()=>g,singleDivModeExecute:()=>Ve,stringToAlpha:()=>yi,stringToRgb:()=>mi,touchCancelEvent:()=>ai,touchEndEvent:()=>Ze,touchMoveEvent:()=>si,touchStartEvent:()=>ii,tsParticles:()=>Vs,visibilityChangeEvent:()=>li});var l,c=function(t,e,i,s,o){if("m"===s)throw new TypeError("Private method is not writable");if("a"===s&&!o)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof e?t!==e||!o:!e.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===s?o.call(t,i):o?o.value=i:e.set(t,i),i},d=function(t,e,i,s){if("a"===i&&!s)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof e?t!==e||!s:!e.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===i?s:"a"===i?s.call(t):s?s.value:e.get(t)};class h{constructor(){l.set(this,void 0),c(this,l,new Map,"f")}addEventListener(t,e){var i;this.removeEventListener(t,e),d(this,l,"f").get(t)||d(this,l,"f").set(t,[]),null===(i=d(this,l,"f").get(t))||void 0===i||i.push(e)}removeEventListener(t,e){const i=d(this,l,"f").get(t);if(!i)return;const s=i.length,o=i.indexOf(e);o<0||(1===s?d(this,l,"f").delete(t):i.splice(o,1))}removeAllEventListeners(t){t?d(this,l,"f").delete(t):c(this,l,new Map,"f")}dispatchEvent(t,e){var i;null===(i=d(this,l,"f").get(t))||void 0===i||i.forEach((t=>t(e)))}hasEventListener(t){return!!d(this,l,"f").get(t)}}l=new WeakMap;class u{constructor(t,e){if("number"!=typeof t&&t)this.x=t.x,this.y=t.y;else{if(void 0===t||void 0===e)throw new Error("tsParticles - Vector not initialized correctly");this.x=t,this.y=e}}static clone(t){return u.create(t.x,t.y)}static create(t,e){return new u(t,e)}static get origin(){return u.create(0,0)}get angle(){return Math.atan2(this.y,this.x)}set angle(t){this.updateFromAngle(t,this.length)}get length(){return Math.sqrt(this.getLengthSq())}set length(t){this.updateFromAngle(this.angle,t)}add(t){return u.create(this.x+t.x,this.y+t.y)}addTo(t){this.x+=t.x,this.y+=t.y}sub(t){return u.create(this.x-t.x,this.y-t.y)}subFrom(t){this.x-=t.x,this.y-=t.y}mult(t){return u.create(this.x*t,this.y*t)}multTo(t){this.x*=t,this.y*=t}div(t){return u.create(this.x/t,this.y/t)}divTo(t){this.x/=t,this.y/=t}distanceTo(t){return this.sub(t).length}getLengthSq(){return this.x**2+this.y**2}distanceToSq(t){return this.sub(t).getLengthSq()}manhattanDistanceTo(t){return Math.abs(t.x-this.x)+Math.abs(t.y-this.y)}copy(){return u.clone(this)}setTo(t){this.x=t.x,this.y=t.y}rotate(t){return u.create(this.x*Math.cos(t)-this.y*Math.sin(t),this.x*Math.sin(t)+this.y*Math.cos(t))}updateFromAngle(t,e){this.x=Math.cos(t)*e,this.y=Math.sin(t)*e}}function p(t,e,i){return Math.min(Math.max(t,e),i)}function v(t,e,i,s){return Math.floor((t*i+e*s)/(i+s))}function f(t){const e=b(t);let i=m(t);return e===i&&(i=0),Math.random()*(e-i)+i}function y(t){return"number"==typeof t?t:f(t)}function m(t){return"number"==typeof t?t:t.min}function b(t){return"number"==typeof t?t:t.max}function g(t,e){if(t===e||void 0===e&&"number"==typeof t)return t;const i=m(t),s=b(t);return void 0!==e?{min:Math.min(i,e),max:Math.max(s,e)}:g(i,s)}function w(t){const e=t.random,{enable:i,minimumValue:s}="boolean"==typeof e?{enable:e,minimumValue:0}:e;return y(i?g(t.value,s):t.value)}function x(t,e){const i=t.x-e.x,s=t.y-e.y;return{dx:i,dy:s,distance:Math.sqrt(i*i+s*s)}}function k(t,e){return x(t,e).distance}function P(t,e,i){if("number"==typeof t)return t*Math.PI/180;switch(t){case"top":return-Math.PI/2;case"top-right":return-Math.PI/4;case"right":return 0;case"bottom-right":return Math.PI/4;case"bottom":return Math.PI/2;case"bottom-left":return 3*Math.PI/4;case"left":return Math.PI;case"top-left":return-3*Math.PI/4;case"inside":return Math.atan2(i.y-e.y,i.x-e.x);case"outside":return Math.atan2(e.y-i.y,e.x-i.x);default:return Math.random()*Math.PI*2}}function M(t){const e=u.origin;return e.length=1,e.angle=t,e}function z(t,e,i,s){return u.create(t.x*(i-s)/(i+s)+2*e.x*s/(i+s),t.y)}function C(t,e){switch(e){case"ease-out-quad":return 1-(1-t)**2;case"ease-out-cubic":return 1-(1-t)**3;case"ease-out-quart":return 1-(1-t)**4;case"ease-out-quint":return 1-(1-t)**5;case"ease-out-expo":return 1===t?1:1-Math.pow(2,-10*t);case"ease-out-sine":return Math.sin(t*Math.PI/2);case"ease-out-back":{const e=1.70158;return 1+(e+1)*Math.pow(t-1,3)+e*Math.pow(t-1,2)}case"ease-out-circ":return Math.sqrt(1-Math.pow(t-1,2));default:return t}}function E(t){var e,i;return void 0!==(null===(e=t.position)||void 0===e?void 0:e.x)&&void 0!==(null===(i=t.position)||void 0===i?void 0:i.y)?{x:t.position.x*t.size.width/100,y:t.position.y*t.size.height/100}:void 0}function T(t){var e,i,s,o;return{x:(null!==(i=null===(e=t.position)||void 0===e?void 0:e.x)&&void 0!==i?i:100*Math.random())*t.size.width/100,y:(null!==(o=null===(s=t.position)||void 0===s?void 0:s.y)&&void 0!==o?o:100*Math.random())*t.size.height/100}}function S(t){var e,i;const s={x:void 0!==(null===(e=t.position)||void 0===e?void 0:e.x)?y(t.position.x):void 0,y:void 0!==(null===(i=t.position)||void 0===i?void 0:i.y)?y(t.position.y):void 0};return T({size:t.size,position:s})}function O(t){var e,i,s,o;return{x:null!==(i=null===(e=t.position)||void 0===e?void 0:e.x)&&void 0!==i?i:Math.random()*t.size.width,y:null!==(o=null===(s=t.position)||void 0===s?void 0:s.y)&&void 0!==o?o:Math.random()*t.size.height}}function R(t){var e,i;const s={x:void 0!==(null===(e=t.position)||void 0===e?void 0:e.x)?y(t.position.x):void 0,y:void 0!==(null===(i=t.position)||void 0===i?void 0:i.y)?y(t.position.y):void 0};return O({size:t.size,position:s})}class A{constructor(){this.value=""}static create(t,e){const i=new A;return i.load(t),void 0!==e&&("string"==typeof e||e instanceof Array?i.load({value:e}):i.load(e)),i}load(t){void 0!==(null==t?void 0:t.value)&&(this.value=t.value)}}class I{constructor(){this.color=new A,this.color.value="",this.image="",this.position="",this.repeat="",this.size="",this.opacity=1}load(t){t&&(void 0!==t.color&&(this.color=A.create(this.color,t.color)),void 0!==t.image&&(this.image=t.image),void 0!==t.position&&(this.position=t.position),void 0!==t.repeat&&(this.repeat=t.repeat),void 0!==t.size&&(this.size=t.size),void 0!==t.opacity&&(this.opacity=t.opacity))}}class D{constructor(){this.color=new A,this.color.value="#fff",this.opacity=1}load(t){t&&(void 0!==t.color&&(this.color=A.create(this.color,t.color)),void 0!==t.opacity&&(this.opacity=t.opacity))}}class L{constructor(){this.composite="destination-out",this.cover=new D,this.enable=!1}load(t){if(t){if(void 0!==t.composite&&(this.composite=t.composite),void 0!==t.cover){const e=t.cover,i="string"==typeof t.cover?{color:t.cover}:t.cover;this.cover.load(void 0!==e.color?e:{color:i})}void 0!==t.enable&&(this.enable=t.enable)}}}class H{constructor(){this.enable=!0,this.zIndex=0}load(t){t&&(void 0!==t.enable&&(this.enable=t.enable),void 0!==t.zIndex&&(this.zIndex=t.zIndex))}}class q{constructor(){this.enable=!1,this.mode=[]}load(t){t&&(void 0!==t.enable&&(this.enable=t.enable),void 0!==t.mode&&(this.mode=t.mode))}}class F{constructor(){this.selectors=[],this.enable=!1,this.mode=[],this.type="circle"}get elementId(){return this.ids}set elementId(t){this.ids=t}get el(){return this.elementId}set el(t){this.elementId=t}get ids(){return this.selectors instanceof Array?this.selectors.map((t=>t.replace("#",""))):this.selectors.replace("#","")}set ids(t){this.selectors=t instanceof Array?t.map((t=>`#${t}`)):`#${t}`}load(t){var e,i;if(!t)return;const s=null!==(i=null!==(e=t.ids)&&void 0!==e?e:t.elementId)&&void 0!==i?i:t.el;void 0!==s&&(this.ids=s),void 0!==t.selectors&&(this.selectors=t.selectors),void 0!==t.enable&&(this.enable=t.enable),void 0!==t.mode&&(this.mode=t.mode),void 0!==t.type&&(this.type=t.type)}}class _{constructor(){this.enable=!1,this.force=2,this.smooth=10}load(t){t&&(void 0!==t.enable&&(this.enable=t.enable),void 0!==t.force&&(this.force=t.force),void 0!==t.smooth&&(this.smooth=t.smooth))}}class B{constructor(){this.enable=!1,this.mode=[],this.parallax=new _}load(t){t&&(void 0!==t.enable&&(this.enable=t.enable),void 0!==t.mode&&(this.mode=t.mode),this.parallax.load(t.parallax))}}class V{constructor(){this.onClick=new q,this.onDiv=new F,this.onHover=new B,this.resize=!0}get onclick(){return this.onClick}set onclick(t){this.onClick=t}get ondiv(){return this.onDiv}set ondiv(t){this.onDiv=t}get onhover(){return this.onHover}set onhover(t){this.onHover=t}load(t){var e,i,s;if(!t)return;this.onClick.load(null!==(e=t.onClick)&&void 0!==e?e:t.onclick);const o=null!==(i=t.onDiv)&&void 0!==i?i:t.ondiv;void 0!==o&&(o instanceof Array?this.onDiv=o.map((t=>{const e=new F;return e.load(t),e})):(this.onDiv=new F,this.onDiv.load(o))),this.onHover.load(null!==(s=t.onHover)&&void 0!==s?s:t.onhover),void 0!==t.resize&&(this.resize=t.resize)}}class W{constructor(){this.distance=200,this.duration=.4,this.easing="ease-out-quad",this.factor=1,this.maxSpeed=50,this.speed=1}load(t){t&&(void 0!==t.distance&&(this.distance=t.distance),void 0!==t.duration&&(this.duration=t.duration),void 0!==t.easing&&(this.easing=t.easing),void 0!==t.factor&&(this.factor=t.factor),void 0!==t.maxSpeed&&(this.maxSpeed=t.maxSpeed),void 0!==t.speed&&(this.speed=t.speed))}}class j{constructor(){this.distance=200}load(t){t&&void 0!==t.distance&&(this.distance=t.distance)}}class G{constructor(){this.distance=200,this.duration=.4,this.mix=!1}load(t){t&&(void 0!==t.distance&&(this.distance=t.distance),void 0!==t.duration&&(this.duration=t.duration),void 0!==t.mix&&(this.mix=t.mix),void 0!==t.opacity&&(this.opacity=t.opacity),void 0!==t.color&&(t.color instanceof Array?this.color=t.color.map((t=>A.create(void 0,t))):(this.color instanceof Array&&(this.color=new A),this.color=A.create(this.color,t.color))),void 0!==t.size&&(this.size=t.size))}}class U extends G{constructor(){super(),this.selectors=[]}get ids(){return this.selectors instanceof Array?this.selectors.map((t=>t.replace("#",""))):this.selectors.replace("#","")}set ids(t){this.selectors=t instanceof Array?t.map((t=>`#${t}`)):`#${t}`}load(t){super.load(t),t&&(void 0!==t.ids&&(this.ids=t.ids),void 0!==t.selectors&&(this.selectors=t.selectors))}}class $ extends G{load(t){super.load(t),t&&(t.divs instanceof Array?this.divs=t.divs.map((t=>{const e=new U;return e.load(t),e})):((this.divs instanceof Array||!this.divs)&&(this.divs=new U),this.divs.load(t.divs)))}}class N{constructor(){this.opacity=.5}load(t){void 0!==t&&void 0!==t.opacity&&void 0!==t.opacity&&(this.opacity=t.opacity)}}class X{constructor(){this.distance=80,this.links=new N,this.radius=60}get line_linked(){return this.links}set line_linked(t){this.links=t}get lineLinked(){return this.links}set lineLinked(t){this.links=t}load(t){var e,i;t&&(void 0!==t.distance&&(this.distance=t.distance),this.links.load(null!==(i=null!==(e=t.links)&&void 0!==e?e:t.lineLinked)&&void 0!==i?i:t.line_linked),void 0!==t.radius&&(this.radius=t.radius))}}class Y{constructor(){this.blink=!1,this.consent=!1,this.opacity=1}load(t){t&&(void 0!==t.blink&&(this.blink=t.blink),void 0!==t.color&&(this.color=A.create(this.color,t.color)),void 0!==t.consent&&(this.consent=t.consent),void 0!==t.opacity&&(this.opacity=t.opacity))}}class J{constructor(){this.distance=100,this.links=new Y}get line_linked(){return this.links}set line_linked(t){this.links=t}get lineLinked(){return this.links}set lineLinked(t){this.links=t}load(t){var e,i;t&&(void 0!==t.distance&&(this.distance=t.distance),this.links.load(null!==(i=null!==(e=t.links)&&void 0!==e?e:t.lineLinked)&&void 0!==i?i:t.line_linked))}}class Q{constructor(){this.start=new A,this.stop=new A,this.start.value="#ffffff",this.stop.value="#000000"}load(t){t&&(this.start=A.create(this.start,t.start),this.stop=A.create(this.stop,t.stop))}}class Z{constructor(){this.gradient=new Q,this.radius=1e3}load(t){t&&(this.gradient.load(t.gradient),void 0!==t.radius&&(this.radius=t.radius))}}class K{constructor(){this.color=new A,this.color.value="#000000",this.length=2e3}load(t){t&&(this.color=A.create(this.color,t.color),void 0!==t.length&&(this.length=t.length))}}class tt{constructor(){this.area=new Z,this.shadow=new K}load(t){t&&(this.area.load(t.area),this.shadow.load(t.shadow))}}class et{constructor(){this.default=!0,this.groups=[],this.quantity=4}get particles_nb(){return this.quantity}set particles_nb(t){this.quantity=t}load(t){var e;if(!t)return;void 0!==t.default&&(this.default=t.default),void 0!==t.groups&&(this.groups=t.groups.map((t=>t))),this.groups.length||(this.default=!0);const i=null!==(e=t.quantity)&&void 0!==e?e:t.particles_nb;void 0!==i&&(this.quantity=i)}}class it{constructor(){this.quantity=2}get particles_nb(){return this.quantity}set particles_nb(t){this.quantity=t}load(t){var e;if(!t)return;const i=null!==(e=t.quantity)&&void 0!==e?e:t.particles_nb;void 0!==i&&(this.quantity=i)}}class st{constructor(){this.distance=200,this.duration=.4,this.factor=100,this.speed=1,this.maxSpeed=50,this.easing="ease-out-quad"}load(t){t&&(void 0!==t.distance&&(this.distance=t.distance),void 0!==t.duration&&(this.duration=t.duration),void 0!==t.easing&&(this.easing=t.easing),void 0!==t.factor&&(this.factor=t.factor),void 0!==t.speed&&(this.speed=t.speed),void 0!==t.maxSpeed&&(this.maxSpeed=t.maxSpeed))}}class ot extends st{constructor(){super(),this.selectors=[]}get ids(){return this.selectors instanceof Array?this.selectors.map((t=>t.replace("#",""))):this.selectors.replace("#","")}set ids(t){this.selectors=t instanceof Array?t.map((()=>`#${t}`)):`#${t}`}load(t){super.load(t),t&&(void 0!==t.ids&&(this.ids=t.ids),void 0!==t.selectors&&(this.selectors=t.selectors))}}class nt extends st{load(t){super.load(t),t&&(t.divs instanceof Array?this.divs=t.divs.map((t=>{const e=new ot;return e.load(t),e})):((this.divs instanceof Array||!this.divs)&&(this.divs=new ot),this.divs.load(t.divs)))}}class at{constructor(){this.factor=3,this.radius=200}get active(){return!1}set active(t){}load(t){t&&(void 0!==t.factor&&(this.factor=t.factor),void 0!==t.radius&&(this.radius=t.radius))}}class rt{constructor(){this.delay=1,this.pauseOnStop=!1,this.quantity=1}load(t){t&&(void 0!==t.delay&&(this.delay=t.delay),void 0!==t.quantity&&(this.quantity=t.quantity),void 0!==t.particles&&(this.particles=Fe({},t.particles)),void 0!==t.pauseOnStop&&(this.pauseOnStop=t.pauseOnStop))}}class lt{constructor(){this.attract=new W,this.bounce=new j,this.bubble=new $,this.connect=new X,this.grab=new J,this.light=new tt,this.push=new et,this.remove=new it,this.repulse=new nt,this.slow=new at,this.trail=new rt}load(t){t&&(this.attract.load(t.attract),this.bubble.load(t.bubble),this.connect.load(t.connect),this.grab.load(t.grab),this.light.load(t.light),this.push.load(t.push),this.remove.load(t.remove),this.repulse.load(t.repulse),this.slow.load(t.slow),this.trail.load(t.trail))}}class ct{constructor(){this.detectsOn="window",this.events=new V,this.modes=new lt}get detect_on(){return this.detectsOn}set detect_on(t){this.detectsOn=t}load(t){var e,i,s;if(!t)return;const o=null!==(e=t.detectsOn)&&void 0!==e?e:t.detect_on;void 0!==o&&(this.detectsOn=o),this.events.load(t.events),this.modes.load(t.modes),!0===(null===(s=null===(i=t.modes)||void 0===i?void 0:i.slow)||void 0===s?void 0:s.active)&&(this.events.onHover.mode instanceof Array?this.events.onHover.mode.indexOf("slow")<0&&this.events.onHover.mode.push("slow"):"slow"!==this.events.onHover.mode&&(this.events.onHover.mode=[this.events.onHover.mode,"slow"]))}}class dt{load(t){var e,i;t&&(void 0!==t.position&&(this.position={x:null!==(e=t.position.x)&&void 0!==e?e:50,y:null!==(i=t.position.y)&&void 0!==i?i:50}),void 0!==t.options&&(this.options=Fe({},t.options)))}}class ht{constructor(){this.factor=4,this.value=!0}load(t){t&&(void 0!==t.factor&&(this.factor=t.factor),void 0!==t.value&&(this.value=t.value))}}class ut{constructor(){this.disable=!1,this.reduce=new ht}load(t){t&&(void 0!==t.disable&&(this.disable=t.disable),this.reduce.load(t.reduce))}}class pt{constructor(){this.maxWidth=1/0,this.options={},this.mode="canvas"}load(t){t&&(void 0!==t.maxWidth&&(this.maxWidth=t.maxWidth),void 0!==t.mode&&("screen"===t.mode?this.mode="screen":this.mode="canvas"),void 0!==t.options&&(this.options=Fe({},t.options)))}}class vt{constructor(){this.auto=!1,this.mode="any",this.value=!1}load(t){t&&(void 0!==t.auto&&(this.auto=t.auto),void 0!==t.mode&&(this.mode=t.mode),void 0!==t.value&&(this.value=t.value))}}class ft{constructor(){this.name="",this.default=new vt}load(t){t&&(void 0!==t.name&&(this.name=t.name),this.default.load(t.default),void 0!==t.options&&(this.options=Fe({},t.options)))}}var yt,mt,bt,gt=function(t,e,i,s,o){if("m"===s)throw new TypeError("Private method is not writable");if("a"===s&&!o)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof e?t!==e||!o:!e.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===s?o.call(t,i):o?o.value=i:e.set(t,i),i},wt=function(t,e,i,s){if("a"===i&&!s)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof e?t!==e||!s:!e.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===i?s:"a"===i?s.call(t):s?s.value:e.get(t)};class xt{constructor(t){yt.add(this),mt.set(this,void 0),gt(this,mt,t,"f"),this.autoPlay=!0,this.background=new I,this.backgroundMask=new L,this.fullScreen=new H,this.detectRetina=!0,this.duration=0,this.fpsLimit=120,this.interactivity=new ct,this.manualParticles=[],this.motion=new ut,this.particles=Xe(),this.pauseOnBlur=!0,this.pauseOnOutsideViewport=!0,this.responsive=[],this.style={},this.themes=[],this.zLayers=100}get fps_limit(){return this.fpsLimit}set fps_limit(t){this.fpsLimit=t}get retina_detect(){return this.detectRetina}set retina_detect(t){this.detectRetina=t}get backgroundMode(){return this.fullScreen}set backgroundMode(t){this.fullScreen.load(t)}load(t){var e,i,s,o,n;if(!t)return;if(void 0!==t.preset)if(t.preset instanceof Array)for(const e of t.preset)this.importPreset(e);else this.importPreset(t.preset);void 0!==t.autoPlay&&(this.autoPlay=t.autoPlay);const a=null!==(e=t.detectRetina)&&void 0!==e?e:t.retina_detect;void 0!==a&&(this.detectRetina=a),void 0!==t.duration&&(this.duration=t.duration);const r=null!==(i=t.fpsLimit)&&void 0!==i?i:t.fps_limit;void 0!==r&&(this.fpsLimit=r),void 0!==t.pauseOnBlur&&(this.pauseOnBlur=t.pauseOnBlur),void 0!==t.pauseOnOutsideViewport&&(this.pauseOnOutsideViewport=t.pauseOnOutsideViewport),void 0!==t.zLayers&&(this.zLayers=t.zLayers),this.background.load(t.background);const l=null!==(s=t.fullScreen)&&void 0!==s?s:t.backgroundMode;if("boolean"==typeof l?this.fullScreen.enable=l:this.fullScreen.load(l),this.backgroundMask.load(t.backgroundMask),this.interactivity.load(t.interactivity),void 0!==t.manualParticles&&(this.manualParticles=t.manualParticles.map((t=>{const e=new dt;return e.load(t),e}))),this.motion.load(t.motion),this.particles.load(t.particles),this.style=Fe(this.style,t.style),wt(this,mt,"f").plugins.loadOptions(this,t),void 0!==t.responsive)for(const e of t.responsive){const t=new pt;t.load(e),this.responsive.push(t)}if(this.responsive.sort(((t,e)=>t.maxWidth-e.maxWidth)),void 0!==t.themes)for(const e of t.themes){const t=new ft;t.load(e),this.themes.push(t)}this.defaultDarkTheme=null===(o=wt(this,yt,"m",bt).call(this,"dark"))||void 0===o?void 0:o.name,this.defaultLightTheme=null===(n=wt(this,yt,"m",bt).call(this,"light"))||void 0===n?void 0:n.name}setTheme(t){if(t){const e=this.themes.find((e=>e.name===t));e&&this.load(e.options)}else{const t="undefined"!=typeof matchMedia&&matchMedia("(prefers-color-scheme: dark)"),e=t&&t.matches,i=wt(this,yt,"m",bt).call(this,e?"dark":"light");i&&this.load(i.options)}}setResponsive(t,e,i){this.load(i);const s=this.responsive.find((i=>"screen"===i.mode&&screen?i.maxWidth*e>screen.availWidth:i.maxWidth*e>t));return this.load(null==s?void 0:s.options),null==s?void 0:s.maxWidth}importPreset(t){this.load(wt(this,mt,"f").plugins.getPreset(t))}}mt=new WeakMap,yt=new WeakSet,bt=function(t){var e;return null!==(e=this.themes.find((e=>e.default.value&&e.default.mode===t)))&&void 0!==e?e:this.themes.find((t=>t.default.value&&"any"===t.default.mode))};class kt{constructor(){this.count=0,this.enable=!1,this.offset=0,this.speed=1,this.sync=!0}load(t){t&&(void 0!==t.count&&(this.count=g(t.count)),void 0!==t.enable&&(this.enable=t.enable),void 0!==t.offset&&(this.offset=g(t.offset)),void 0!==t.speed&&(this.speed=g(t.speed)),void 0!==t.sync&&(this.sync=t.sync))}}class Pt{constructor(){this.h=new kt,this.s=new kt,this.l=new kt}load(t){t&&(this.h.load(t.h),this.s.load(t.s),this.l.load(t.l))}}class Mt extends A{constructor(){super(),this.animation=new Pt}static create(t,e){const i=new Mt;return i.load(t),void 0!==e&&("string"==typeof e||e instanceof Array?i.load({value:e}):i.load(e)),i}load(t){if(super.load(t),!t)return;const e=t.animation;void 0!==e&&(void 0!==e.enable?this.animation.h.load(e):this.animation.load(t.animation))}}class zt{constructor(){this.angle=new Ct,this.colors=[],this.type="random"}load(t){t&&(this.angle.load(t.angle),void 0!==t.colors&&(this.colors=t.colors.map((t=>{const e=new Tt;return e.load(t),e}))),void 0!==t.type&&(this.type=t.type))}}class Ct{constructor(){this.value=0,this.animation=new St,this.direction="clockwise"}load(t){t&&(this.animation.load(t.animation),void 0!==t.value&&(this.value=t.value),void 0!==t.direction&&(this.direction=t.direction))}}class Et{constructor(){this.value=0,this.animation=new Ot}load(t){t&&(this.animation.load(t.animation),void 0!==t.value&&(this.value=g(t.value)))}}class Tt{constructor(){this.stop=0,this.value=new Mt}load(t){t&&(void 0!==t.stop&&(this.stop=t.stop),this.value=Mt.create(this.value,t.value),void 0!==t.opacity&&(this.opacity=new Et,"number"==typeof t.opacity?this.opacity.value=t.opacity:this.opacity.load(t.opacity)))}}class St{constructor(){this.count=0,this.enable=!1,this.speed=0,this.sync=!1}load(t){t&&(void 0!==t.count&&(this.count=g(t.count)),void 0!==t.enable&&(this.enable=t.enable),void 0!==t.speed&&(this.speed=g(t.speed)),void 0!==t.sync&&(this.sync=t.sync))}}class Ot{constructor(){this.count=0,this.enable=!1,this.speed=0,this.sync=!1,this.startValue="random"}load(t){t&&(void 0!==t.count&&(this.count=g(t.count)),void 0!==t.enable&&(this.enable=t.enable),void 0!==t.speed&&(this.speed=g(t.speed)),void 0!==t.sync&&(this.sync=t.sync),void 0!==t.startValue&&(this.startValue=t.startValue))}}class Rt{constructor(){this.enable=!0,this.retries=0}load(t){t&&(void 0!==t.enable&&(this.enable=t.enable),void 0!==t.retries&&(this.retries=t.retries))}}class At{constructor(){this.enable=!1,this.minimumValue=0}load(t){t&&(void 0!==t.enable&&(this.enable=t.enable),void 0!==t.minimumValue&&(this.minimumValue=t.minimumValue))}}class It{constructor(){this.random=new At,this.value=0}load(t){t&&("boolean"==typeof t.random?this.random.enable=t.random:this.random.load(t.random),void 0!==t.value&&(this.value=g(t.value,this.random.enable?this.random.minimumValue:void 0)))}}class Dt extends It{constructor(){super(),this.random.minimumValue=.1,this.value=1}}class Lt{constructor(){this.horizontal=new Dt,this.vertical=new Dt}load(t){t&&(this.horizontal.load(t.horizontal),this.vertical.load(t.vertical))}}class Ht{constructor(){this.bounce=new Lt,this.enable=!1,this.mode="bounce",this.overlap=new Rt}load(t){t&&(this.bounce.load(t.bounce),void 0!==t.enable&&(this.enable=t.enable),void 0!==t.mode&&(this.mode=t.mode),this.overlap.load(t.overlap))}}class qt extends It{constructor(){super(),this.value=3}}class Ft extends It{constructor(){super(),this.value={min:4,max:9}}}class _t{constructor(){this.count=1,this.factor=new qt,this.rate=new Ft,this.sizeOffset=!0}load(t){t&&(void 0!==t.count&&(this.count=t.count),this.factor.load(t.factor),this.rate.load(t.rate),void 0!==t.particles&&(this.particles=Fe({},t.particles)),void 0!==t.sizeOffset&&(this.sizeOffset=t.sizeOffset))}}class Bt{constructor(){this.mode="none",this.split=new _t}load(t){t&&(void 0!==t.mode&&(this.mode=t.mode),this.split.load(t.split))}}class Vt extends It{constructor(){super(),this.sync=!1}load(t){t&&(super.load(t),void 0!==t.sync&&(this.sync=t.sync))}}class Wt extends It{constructor(){super(),this.random.minimumValue=1e-4,this.sync=!1}load(t){t&&(super.load(t),void 0!==t.sync&&(this.sync=t.sync))}}class jt{constructor(){this.count=0,this.delay=new Vt,this.duration=new Wt}load(t){t&&(void 0!==t.count&&(this.count=t.count),this.delay.load(t.delay),this.duration.load(t.duration))}}class Gt{constructor(){this.blur=5,this.color=new A,this.color.value="#000",this.enable=!1}load(t){t&&(void 0!==t.blur&&(this.blur=t.blur),this.color=A.create(this.color,t.color),void 0!==t.enable&&(this.enable=t.enable))}}class Ut{constructor(){this.enable=!1,this.frequency=1}load(t){t&&(void 0!==t.color&&(this.color=A.create(this.color,t.color)),void 0!==t.enable&&(this.enable=t.enable),void 0!==t.frequency&&(this.frequency=t.frequency),void 0!==t.opacity&&(this.opacity=t.opacity))}}class $t{constructor(){this.blink=!1,this.color=new A,this.color.value="#fff",this.consent=!1,this.distance=100,this.enable=!1,this.frequency=1,this.opacity=1,this.shadow=new Gt,this.triangles=new Ut,this.width=1,this.warp=!1}load(t){t&&(void 0!==t.id&&(this.id=t.id),void 0!==t.blink&&(this.blink=t.blink),this.color=A.create(this.color,t.color),void 0!==t.consent&&(this.consent=t.consent),void 0!==t.distance&&(this.distance=t.distance),void 0!==t.enable&&(this.enable=t.enable),void 0!==t.frequency&&(this.frequency=t.frequency),void 0!==t.opacity&&(this.opacity=t.opacity),this.shadow.load(t.shadow),this.triangles.load(t.triangles),void 0!==t.width&&(this.width=t.width),void 0!==t.warp&&(this.warp=t.warp))}}class Nt{constructor(){this.offset=0,this.value=90}load(t){t&&(void 0!==t.offset&&(this.offset=g(t.offset)),void 0!==t.value&&(this.value=g(t.value)))}}class Xt{constructor(){this.distance=200,this.enable=!1,this.rotate={x:3e3,y:3e3}}get rotateX(){return this.rotate.x}set rotateX(t){this.rotate.x=t}get rotateY(){return this.rotate.y}set rotateY(t){this.rotate.y=t}load(t){var e,i,s,o;if(!t)return;void 0!==t.distance&&(this.distance=g(t.distance)),void 0!==t.enable&&(this.enable=t.enable);const n=null!==(i=null===(e=t.rotate)||void 0===e?void 0:e.x)&&void 0!==i?i:t.rotateX;void 0!==n&&(this.rotate.x=n);const a=null!==(o=null===(s=t.rotate)||void 0===s?void 0:s.y)&&void 0!==o?o:t.rotateY;void 0!==a&&(this.rotate.y=a)}}class Yt{constructor(){this.acceleration=9.81,this.enable=!1,this.inverse=!1,this.maxSpeed=50}load(t){t&&(void 0!==t.acceleration&&(this.acceleration=g(t.acceleration)),void 0!==t.enable&&(this.enable=t.enable),void 0!==t.inverse&&(this.inverse=t.inverse),void 0!==t.maxSpeed&&(this.maxSpeed=g(t.maxSpeed)))}}class Jt extends It{constructor(){super()}}class Qt{constructor(){this.clamp=!0,this.delay=new Jt,this.enable=!1,this.options={}}load(t){t&&(void 0!==t.clamp&&(this.clamp=t.clamp),this.delay.load(t.delay),void 0!==t.enable&&(this.enable=t.enable),this.generator=t.generator,t.options&&(this.options=Fe(this.options,t.options)))}}class Zt{constructor(){this.enable=!1,this.length=10,this.fillColor=new A,this.fillColor.value="#000000"}load(t){t&&(void 0!==t.enable&&(this.enable=t.enable),this.fillColor=A.create(this.fillColor,t.fillColor),void 0!==t.length&&(this.length=t.length))}}class Kt{constructor(){this.default="out"}load(t){var e,i,s,o;t&&(void 0!==t.default&&(this.default=t.default),this.bottom=null!==(e=t.bottom)&&void 0!==e?e:t.default,this.left=null!==(i=t.left)&&void 0!==i?i:t.default,this.right=null!==(s=t.right)&&void 0!==s?s:t.default,this.top=null!==(o=t.top)&&void 0!==o?o:t.default)}}class te{constructor(){this.acceleration=0,this.enable=!1}load(t){t&&(void 0!==t.acceleration&&(this.acceleration=g(t.acceleration)),void 0!==t.enable&&(this.enable=t.enable),this.position=t.position?Fe({},t.position):void 0)}}class ee{constructor(){this.angle=new Nt,this.attract=new Xt,this.center={x:50,y:50,radius:0},this.decay=0,this.distance={},this.direction="none",this.drift=0,this.enable=!1,this.gravity=new Yt,this.path=new Qt,this.outModes=new Kt,this.random=!1,this.size=!1,this.speed=2,this.spin=new te,this.straight=!1,this.trail=new Zt,this.vibrate=!1,this.warp=!1}get collisions(){return!1}set collisions(t){}get bounce(){return this.collisions}set bounce(t){this.collisions=t}get out_mode(){return this.outMode}set out_mode(t){this.outMode=t}get outMode(){return this.outModes.default}set outMode(t){this.outModes.default=t}get noise(){return this.path}set noise(t){this.path=t}load(t){var e,i,s;if(!t)return;void 0!==t.angle&&("number"==typeof t.angle?this.angle.value=t.angle:this.angle.load(t.angle)),this.attract.load(t.attract),this.center=Fe(this.center,t.center),void 0!==t.decay&&(this.decay=t.decay),void 0!==t.direction&&(this.direction=t.direction),void 0!==t.distance&&(this.distance="number"==typeof t.distance?{horizontal:t.distance,vertical:t.distance}:Fe({},t.distance)),void 0!==t.drift&&(this.drift=g(t.drift)),void 0!==t.enable&&(this.enable=t.enable),this.gravity.load(t.gravity);const o=null!==(e=t.outMode)&&void 0!==e?e:t.out_mode;void 0===t.outModes&&void 0===o||("string"==typeof t.outModes||void 0===t.outModes&&void 0!==o?this.outModes.load({default:null!==(i=t.outModes)&&void 0!==i?i:o}):this.outModes.load(t.outModes)),this.path.load(null!==(s=t.path)&&void 0!==s?s:t.noise),void 0!==t.random&&(this.random=t.random),void 0!==t.size&&(this.size=t.size),void 0!==t.speed&&(this.speed=g(t.speed)),this.spin.load(t.spin),void 0!==t.straight&&(this.straight=t.straight),this.trail.load(t.trail),void 0!==t.vibrate&&(this.vibrate=t.vibrate),void 0!==t.warp&&(this.warp=t.warp)}}class ie{constructor(){this.count=0,this.enable=!1,this.speed=1,this.sync=!1}load(t){t&&(void 0!==t.count&&(this.count=g(t.count)),void 0!==t.enable&&(this.enable=t.enable),void 0!==t.speed&&(this.speed=g(t.speed)),void 0!==t.sync&&(this.sync=t.sync))}}class se extends ie{constructor(){super(),this.destroy="none",this.enable=!1,this.speed=2,this.startValue="random",this.sync=!1}get opacity_min(){return this.minimumValue}set opacity_min(t){this.minimumValue=t}load(t){var e;t&&(super.load(t),void 0!==t.destroy&&(this.destroy=t.destroy),void 0!==t.enable&&(this.enable=t.enable),this.minimumValue=null!==(e=t.minimumValue)&&void 0!==e?e:t.opacity_min,void 0!==t.speed&&(this.speed=t.speed),void 0!==t.startValue&&(this.startValue=t.startValue),void 0!==t.sync&&(this.sync=t.sync))}}class oe extends It{constructor(){super(),this.animation=new se,this.random.minimumValue=.1,this.value=1}get anim(){return this.animation}set anim(t){this.animation=t}load(t){var e;if(!t)return;super.load(t);const i=null!==(e=t.animation)&&void 0!==e?e:t.anim;void 0!==i&&(this.animation.load(i),this.value=g(this.value,this.animation.enable?this.animation.minimumValue:void 0))}}class ne extends It{constructor(){super(),this.value=45,this.random.enable=!1,this.random.minimumValue=0}load(t){void 0!==t&&super.load(t)}}class ae{constructor(){this.animation=new ie,this.enable=!1,this.opacity=1,this.rotation=new ne,this.width=1}load(t){t&&(this.animation.load(t.animation),this.rotation.load(t.rotation),void 0!==t.enable&&(this.enable=t.enable),void 0!==t.opacity&&(this.opacity=g(t.opacity)),void 0!==t.width&&(this.width=g(t.width)),void 0!==t.radius&&(this.radius=g(t.radius)),void 0!==t.color&&(this.color=A.create(this.color,t.color)))}}class re{constructor(){this.enable=!1,this.area=800,this.factor=1e3}get value_area(){return this.area}set value_area(t){this.area=t}load(t){var e;if(!t)return;void 0!==t.enable&&(this.enable=t.enable);const i=null!==(e=t.area)&&void 0!==e?e:t.value_area;void 0!==i&&(this.area=i),void 0!==t.factor&&(this.factor=t.factor)}}class le{constructor(){this.density=new re,this.limit=0,this.value=100}get max(){return this.limit}set max(t){this.limit=t}load(t){var e;if(!t)return;this.density.load(t.density);const i=null!==(e=t.limit)&&void 0!==e?e:t.max;void 0!==i&&(this.limit=i),void 0!==t.value&&(this.value=t.value)}}class ce extends It{constructor(){super(),this.enabled=!1,this.distance=1,this.duration=1,this.factor=1,this.speed=1}load(t){super.load(t),t&&(void 0!==t.enabled&&(this.enabled=t.enabled),void 0!==t.distance&&(this.distance=g(t.distance)),void 0!==t.duration&&(this.duration=g(t.duration)),void 0!==t.factor&&(this.factor=g(t.factor)),void 0!==t.speed&&(this.speed=g(t.speed)))}}class de{constructor(){this.enable=!1,this.value=0}load(t){t&&(void 0!==t.enable&&(this.enable=t.enable),void 0!==t.value&&(this.value=g(t.value)))}}class he{constructor(){this.darken=new de,this.enable=!1,this.enlighten=new de,this.mode="vertical",this.speed=25}load(t){t&&(void 0!==t.backColor&&(this.backColor=A.create(this.backColor,t.backColor)),this.darken.load(t.darken),void 0!==t.enable&&(this.enable=t.enable),this.enlighten.load(t.enlighten),void 0!==t.mode&&(this.mode=t.mode),void 0!==t.speed&&(this.speed=g(t.speed)))}}class ue{constructor(){this.enable=!1,this.speed=0,this.sync=!1}load(t){t&&(void 0!==t.enable&&(this.enable=t.enable),void 0!==t.speed&&(this.speed=g(t.speed)),void 0!==t.sync&&(this.sync=t.sync))}}class pe extends It{constructor(){super(),this.animation=new ue,this.direction="clockwise",this.path=!1,this.value=0}load(t){t&&(super.load(t),void 0!==t.direction&&(this.direction=t.direction),this.animation.load(t.animation),void 0!==t.path&&(this.path=t.path))}}class ve{constructor(){this.blur=0,this.color=new A,this.enable=!1,this.offset={x:0,y:0},this.color.value="#000"}load(t){t&&(void 0!==t.blur&&(this.blur=t.blur),this.color=A.create(this.color,t.color),void 0!==t.enable&&(this.enable=t.enable),void 0!==t.offset&&(void 0!==t.offset.x&&(this.offset.x=t.offset.x),void 0!==t.offset.y&&(this.offset.y=t.offset.y)))}}class fe{constructor(){this.options={},this.type="circle"}get image(){var t;return null!==(t=this.options.image)&&void 0!==t?t:this.options.images}set image(t){this.options.image=t,this.options.images=t}get custom(){return this.options}set custom(t){this.options=t}get images(){return this.image}set images(t){this.image=t}get stroke(){return[]}set stroke(t){}get character(){var t;return null!==(t=this.options.character)&&void 0!==t?t:this.options.char}set character(t){this.options.character=t,this.options.char=t}get polygon(){var t;return null!==(t=this.options.polygon)&&void 0!==t?t:this.options.star}set polygon(t){this.options.polygon=t,this.options.star=t}load(t){var e,i,s;if(!t)return;const o=null!==(e=t.options)&&void 0!==e?e:t.custom;if(void 0!==o)for(const t in o){const e=o[t];e&&(this.options[t]=Fe(null!==(i=this.options[t])&&void 0!==i?i:{},e))}this.loadShape(t.character,"character","char",!0),this.loadShape(t.polygon,"polygon","star",!1),this.loadShape(null!==(s=t.image)&&void 0!==s?s:t.images,"image","images",!0),void 0!==t.type&&(this.type=t.type)}loadShape(t,e,i,s){var o,n,a,r;void 0!==t&&(t instanceof Array?(this.options[e]instanceof Array||(this.options[e]=[],this.options[i]&&!s||(this.options[i]=[])),this.options[e]=Fe(null!==(o=this.options[e])&&void 0!==o?o:[],t),this.options[i]&&!s||(this.options[i]=Fe(null!==(n=this.options[i])&&void 0!==n?n:[],t))):(this.options[e]instanceof Array&&(this.options[e]={},this.options[i]&&!s||(this.options[i]={})),this.options[e]=Fe(null!==(a=this.options[e])&&void 0!==a?a:{},t),this.options[i]&&!s||(this.options[i]=Fe(null!==(r=this.options[i])&&void 0!==r?r:{},t))))}}class ye extends ie{constructor(){super(),this.destroy="none",this.enable=!1,this.speed=5,this.startValue="random",this.sync=!1}get size_min(){return this.minimumValue}set size_min(t){this.minimumValue=t}load(t){var e;super.load(t),t&&(void 0!==t.destroy&&(this.destroy=t.destroy),void 0!==t.enable&&(this.enable=t.enable),this.minimumValue=null!==(e=t.minimumValue)&&void 0!==e?e:t.size_min,void 0!==t.speed&&(this.speed=t.speed),void 0!==t.startValue&&(this.startValue=t.startValue),void 0!==t.sync&&(this.sync=t.sync))}}class me extends It{constructor(){super(),this.animation=new ye,this.random.minimumValue=1,this.value=3}get anim(){return this.animation}set anim(t){this.animation=t}load(t){var e;if(super.load(t),!t)return;const i=null!==(e=t.animation)&&void 0!==e?e:t.anim;void 0!==i&&(this.animation.load(i),this.value=g(this.value,this.animation.enable?this.animation.minimumValue:void 0))}}class be{constructor(){this.width=0}load(t){t&&(void 0!==t.color&&(this.color=Mt.create(this.color,t.color)),void 0!==t.width&&(this.width=t.width),void 0!==t.opacity&&(this.opacity=t.opacity))}}class ge{constructor(){this.enable=!1,this.speed=0,this.sync=!1}load(t){t&&(void 0!==t.enable&&(this.enable=t.enable),void 0!==t.speed&&(this.speed=g(t.speed)),void 0!==t.sync&&(this.sync=t.sync))}}class we extends It{constructor(){super(),this.animation=new ge,this.direction="clockwise",this.enable=!1,this.value=0}load(t){super.load(t),t&&(this.animation.load(t.animation),void 0!==t.direction&&(this.direction=t.direction),void 0!==t.enable&&(this.enable=t.enable))}}class xe{constructor(){this.enable=!1,this.frequency=.05,this.opacity=1}load(t){t&&(void 0!==t.color&&(this.color=A.create(this.color,t.color)),void 0!==t.enable&&(this.enable=t.enable),void 0!==t.frequency&&(this.frequency=t.frequency),void 0!==t.opacity&&(this.opacity=g(t.opacity)))}}class ke{constructor(){this.lines=new xe,this.particles=new xe}load(t){t&&(this.lines.load(t.lines),this.particles.load(t.particles))}}class Pe{constructor(){this.distance=5,this.enable=!1,this.speed=50}load(t){t&&(void 0!==t.distance&&(this.distance=g(t.distance)),void 0!==t.enable&&(this.enable=t.enable),void 0!==t.speed&&(this.speed=g(t.speed)))}}class Me extends It{constructor(){super(),this.opacityRate=1,this.sizeRate=1,this.velocityRate=1}load(t){super.load(t),t&&(void 0!==t.opacityRate&&(this.opacityRate=t.opacityRate),void 0!==t.sizeRate&&(this.sizeRate=t.sizeRate),void 0!==t.velocityRate&&(this.velocityRate=t.velocityRate))}}class ze{constructor(){this.bounce=new Lt,this.collisions=new Ht,this.color=new Mt,this.color.value="#fff",this.destroy=new Bt,this.gradient=[],this.groups={},this.life=new jt,this.links=new $t,this.move=new ee,this.number=new le,this.opacity=new oe,this.orbit=new ae,this.reduceDuplicates=!1,this.repulse=new ce,this.roll=new he,this.rotate=new pe,this.shadow=new ve,this.shape=new fe,this.size=new me,this.stroke=new be,this.tilt=new we,this.twinkle=new ke,this.wobble=new Pe,this.zIndex=new Me}get line_linked(){return this.links}set line_linked(t){this.links=t}get lineLinked(){return this.links}set lineLinked(t){this.links=t}load(t){var e,i,s,o,n,a,r,l;if(!t)return;this.bounce.load(t.bounce),this.color.load(Mt.create(this.color,t.color)),this.destroy.load(t.destroy),this.life.load(t.life);const c=null!==(i=null!==(e=t.links)&&void 0!==e?e:t.lineLinked)&&void 0!==i?i:t.line_linked;if(void 0!==c&&this.links.load(c),void 0!==t.groups)for(const e in t.groups){const i=t.groups[e];void 0!==i&&(this.groups[e]=Fe(null!==(s=this.groups[e])&&void 0!==s?s:{},i))}this.move.load(t.move),this.number.load(t.number),this.opacity.load(t.opacity),this.orbit.load(t.orbit),void 0!==t.reduceDuplicates&&(this.reduceDuplicates=t.reduceDuplicates),this.repulse.load(t.repulse),this.roll.load(t.roll),this.rotate.load(t.rotate),this.shape.load(t.shape),this.size.load(t.size),this.shadow.load(t.shadow),this.tilt.load(t.tilt),this.twinkle.load(t.twinkle),this.wobble.load(t.wobble),this.zIndex.load(t.zIndex);const d=null!==(n=null===(o=t.move)||void 0===o?void 0:o.collisions)&&void 0!==n?n:null===(a=t.move)||void 0===a?void 0:a.bounce;void 0!==d&&(this.collisions.enable=d),this.collisions.load(t.collisions);const h=null!==(r=t.stroke)&&void 0!==r?r:null===(l=t.shape)||void 0===l?void 0:l.stroke;h&&(h instanceof Array?this.stroke=h.map((t=>{const e=new be;return e.load(t),e})):(this.stroke instanceof Array&&(this.stroke=new be),this.stroke.load(h)));const u=t.gradient;u&&(u instanceof Array?this.gradient=u.map((t=>{const e=new zt;return e.load(t),e})):(this.gradient instanceof Array&&(this.gradient=new zt),this.gradient.load(u)))}}function Ce(t,e,i,s,o,n){const a={bounced:!1};return e.mins.max||e.maxs.max||(t.max>=i.min&&t.max<=(i.max+i.min)/2&&o>0||t.min<=i.max&&t.min>(i.max+i.min)/2&&o<0)&&(a.velocity=o*-n,a.bounced=!0),a}function Ee(t,e){if(!(e instanceof Array))return t.matches(e);for(const i of e)if(t.matches(i))return!0;return!1}function Te(){return"undefined"==typeof window||!window||void 0===window.document||!window.document}function Se(){return Te()?t=>setTimeout(t):t=>(window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||window.setTimeout)(t)}function Oe(){return Te()?t=>clearTimeout(t):t=>(window.cancelAnimationFrame||window.webkitCancelRequestAnimationFrame||window.mozCancelRequestAnimationFrame||window.oCancelRequestAnimationFrame||window.msCancelRequestAnimationFrame||window.clearTimeout)(t)}function Re(t,e){return t===e||e instanceof Array&&e.indexOf(t)>-1}async function Ae(t,e){try{await document.fonts.load(`${null!=e?e:"400"} 36px '${null!=t?t:"Verdana"}'`)}catch(t){}}function Ie(t){return Math.floor(Math.random()*t.length)}function De(t,e,i=!0){return t[void 0!==e&&i?e%t.length:Ie(t)]}function Le(t,e,i,s,o){return He(qe(t,null!=s?s:0),e,i,o)}function He(t,e,i,s){let o=!0;return s&&"bottom"!==s||(o=t.topi.x),!o||s&&"right"!==s||(o=t.lefti.y),o}function qe(t,e){return{bottom:t.y+e,left:t.x-e,right:t.x+e,top:t.y-e}}function Fe(t,...e){for(const i of e){if(null==i)continue;if("object"!=typeof i){t=i;continue}const e=Array.isArray(i);!e||"object"==typeof t&&t&&Array.isArray(t)?e||"object"==typeof t&&t&&!Array.isArray(t)||(t={}):t=[];for(const e in i){if("__proto__"===e)continue;const s=i[e],o="object"==typeof s,n=t;n[e]=o&&Array.isArray(s)?s.map((t=>Fe(n[e],t))):Fe(n[e],s)}}return t}function _e(t,e){return e instanceof Array?!!e.find((e=>e.enable&&Re(t,e.mode))):Re(t,e.mode)}function Be(t,e,i){if(e instanceof Array)for(const s of e){const e=s.mode;s.enable&&Re(t,e)&&Ve(s,i)}else{const s=e.mode;e.enable&&Re(t,s)&&Ve(e,i)}}function Ve(t,e){const i=t.selectors;if(i instanceof Array)for(const s of i)e(s,t);else e(i,t)}function We(t,e){if(e&&t)return t instanceof Array?t.find((t=>Ee(e,t.selectors))):Ee(e,t.selectors)?t:void 0}function je(t){return{position:t.getPosition(),radius:t.getRadius(),mass:t.getMass(),velocity:t.velocity,factor:u.create(w(t.options.bounce.horizontal),w(t.options.bounce.vertical))}}function Ge(t,e){const{x:i,y:s}=t.velocity.sub(e.velocity),[o,n]=[t.position,e.position],{dx:a,dy:r}=x(n,o);if(i*a+s*r<0)return;const l=-Math.atan2(r,a),c=t.mass,d=e.mass,h=t.velocity.rotate(l),u=e.velocity.rotate(l),p=z(h,u,c,d),v=z(u,h,c,d),f=p.rotate(-l),y=v.rotate(-l);t.velocity.x=f.x*t.factor.x,t.velocity.y=f.y*t.factor.y,e.velocity.x=y.x*e.factor.x,e.velocity.y=y.y*e.factor.y}function Ue(t,e){const i=qe(t.getPosition(),t.getRadius()),s=Ce({min:i.left,max:i.right},{min:i.top,max:i.bottom},{min:e.left,max:e.right},{min:e.top,max:e.bottom},t.velocity.x,w(t.options.bounce.horizontal));s.bounced&&(void 0!==s.velocity&&(t.velocity.x=s.velocity),void 0!==s.position&&(t.position.x=s.position));const o=Ce({min:i.top,max:i.bottom},{min:i.left,max:i.right},{min:e.top,max:e.bottom},{min:e.left,max:e.right},t.velocity.y,w(t.options.bounce.vertical));o.bounced&&(void 0!==o.velocity&&(t.velocity.y=o.velocity),void 0!==o.position&&(t.position.y=o.position))}function $e(t,...e){for(const i of e)t.load(i)}function Ne(t,...e){const i=new xt(t);return $e(i,...e),i}function Xe(...t){const e=new ze;return $e(e,...t),e}const Ye="generated",Je="random",Qe="mid",Ze="touchend",Ke="mousedown",ti="mouseup",ei="mousemove",ii="touchstart",si="touchmove",oi="mouseleave",ni="mouseout",ai="touchcancel",ri="resize",li="visibilitychange",ci="No polygon data loaded.",di="No polygon found, you need to specify SVG url in config.";function hi(t,e,i){let s=i;return s<0&&(s+=1),s>1&&(s-=1),s<1/6?t+6*(e-t)*s:s<.5?e:s<2/3?t+(e-t)*(2/3-s)*6:t}function ui(t){if(t.startsWith("rgb")){const e=/rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*([\d.]+)\s*)?\)/i.exec(t);return e?{a:e.length>4?parseFloat(e[5]):1,b:parseInt(e[3],10),g:parseInt(e[2],10),r:parseInt(e[1],10)}:void 0}if(t.startsWith("hsl")){const e=/hsla?\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*(,\s*([\d.]+)\s*)?\)/i.exec(t);return e?gi({a:e.length>4?parseFloat(e[5]):1,h:parseInt(e[1],10),l:parseInt(e[3],10),s:parseInt(e[2],10)}):void 0}if(t.startsWith("hsv")){const e=/hsva?\(\s*(\d+)°\s*,\s*(\d+)%\s*,\s*(\d+)%\s*(,\s*([\d.]+)\s*)?\)/i.exec(t);return e?zi({a:e.length>4?parseFloat(e[5]):1,h:parseInt(e[1],10),s:parseInt(e[2],10),v:parseInt(e[3],10)}):void 0}{const e=/^#?([a-f\d])([a-f\d])([a-f\d])([a-f\d])?$/i,i=t.replace(e,((t,e,i,s,o)=>e+e+i+i+s+s+(void 0!==o?o+o:""))),s=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})?$/i.exec(i);return s?{a:void 0!==s[4]?parseInt(s[4],16)/255:1,b:parseInt(s[3],16),g:parseInt(s[2],16),r:parseInt(s[1],16)}:void 0}}function pi(t,e,i=!0){var s,o,n;if(void 0===t)return;const a="string"==typeof t?{value:t}:t;let r;if("string"==typeof a.value)r=a.value===Je?Ti():mi(a.value);else if(a.value instanceof Array){r=pi({value:De(a.value,e,i)})}else{const t=a.value,e=null!==(s=t.rgb)&&void 0!==s?s:a.value;if(void 0!==e.r)r=e;else{const e=null!==(o=t.hsl)&&void 0!==o?o:a.value;if(void 0!==e.h&&void 0!==e.l)r=bi(e);else{const e=null!==(n=t.hsv)&&void 0!==n?n:a.value;void 0!==e.h&&void 0!==e.v&&(r=Mi(e))}}}return r}function vi(t,e,i=!0){const s=pi(t,e,i);return void 0!==s?fi(s):void 0}function fi(t){const e=t.r/255,i=t.g/255,s=t.b/255,o=Math.max(e,i,s),n=Math.min(e,i,s),a={h:0,l:(o+n)/2,s:0};return o!==n&&(a.s=a.l<.5?(o-n)/(o+n):(o-n)/(2-o-n),a.h=e===o?(i-s)/(o-n):a.h=i===o?2+(s-e)/(o-n):4+(e-i)/(o-n)),a.l*=100,a.s*=100,a.h*=60,a.h<0&&(a.h+=360),a}function yi(t){var e;return null===(e=ui(t))||void 0===e?void 0:e.a}function mi(t){return ui(t)}function bi(t){const e={b:0,g:0,r:0},i={h:t.h/360,l:t.l/100,s:t.s/100};if(0===i.s)e.b=i.l,e.g=i.l,e.r=i.l;else{const t=i.l<.5?i.l*(1+i.s):i.l+i.s-i.l*i.s,s=2*i.l-t;e.r=hi(s,t,i.h+1/3),e.g=hi(s,t,i.h),e.b=hi(s,t,i.h-1/3)}return e.r=Math.floor(255*e.r),e.g=Math.floor(255*e.g),e.b=Math.floor(255*e.b),e}function gi(t){const e=bi(t);return{a:t.a,b:e.b,g:e.g,r:e.r}}function wi(t){const e=t.l/100,i=e+t.s/100*Math.min(e,1-e),s=i?2*(1-e/i):0;return{h:t.h,s:100*s,v:100*i}}function xi(t){const e=wi(t);return{a:t.a,h:e.h,s:e.s,v:e.v}}function ki(t){const e=t.v/100,i=e*(1-t.s/100/2),s=0===i||1===i?0:(e-i)/Math.min(i,1-i);return{h:t.h,l:100*i,s:100*s}}function Pi(t){const e=ki(t);return{a:t.a,h:e.h,l:e.l,s:e.s}}function Mi(t){const e={b:0,g:0,r:0},i=t.h/60,s=t.s/100,o=t.v/100,n=o*s,a=n*(1-Math.abs(i%2-1));let r;if(i>=0&&i<=1?r={r:n,g:a,b:0}:i>1&&i<=2?r={r:a,g:n,b:0}:i>2&&i<=3?r={r:0,g:n,b:a}:i>3&&i<=4?r={r:0,g:a,b:n}:i>4&&i<=5?r={r:a,g:0,b:n}:i>5&&i<=6&&(r={r:n,g:0,b:a}),r){const t=o-n;e.r=Math.floor(255*(r.r+t)),e.g=Math.floor(255*(r.g+t)),e.b=Math.floor(255*(r.b+t))}return e}function zi(t){const e=Mi(t);return{a:t.a,b:e.b,g:e.g,r:e.r}}function Ci(t){const e={r:t.r/255,g:t.g/255,b:t.b/255},i=Math.max(e.r,e.g,e.b),s=i-Math.min(e.r,e.g,e.b);let o=0;i===e.r?o=(e.g-e.b)/s*60:i===e.g?o=60*(2+(e.b-e.r)/s):i===e.b&&(o=60*(4+(e.r-e.g)/s));return{h:o,s:100*(i?s/i:0),v:100*i}}function Ei(t){const e=Ci(t);return{a:t.a,h:e.h,s:e.s,v:e.v}}function Ti(t){const e=null!=t?t:0;return{b:Math.floor(f(g(e,256))),g:Math.floor(f(g(e,256))),r:Math.floor(f(g(e,256)))}}function Si(t,e){return`rgba(${t.r}, ${t.g}, ${t.b}, ${null!=e?e:1})`}function Oi(t,e){return`hsla(${t.h}, ${t.s}%, ${t.l}%, ${null!=e?e:1})`}function Ri(t,e){return Oi(ki(t),e)}function Ai(t,e,i,s){let o=t,n=e;return void 0===o.r&&(o=bi(t)),void 0===n.r&&(n=bi(e)),{b:v(o.b,n.b,i,s),g:v(o.g,n.g,i,s),r:v(o.r,n.r,i,s)}}function Ii(t,e,i){var s,o;if(i===Je)return Ti();if("mid"!==i)return i;{const i=null!==(s=t.getFillColor())&&void 0!==s?s:t.getStrokeColor(),n=null!==(o=null==e?void 0:e.getFillColor())&&void 0!==o?o:null==e?void 0:e.getStrokeColor();if(i&&n&&e)return Ai(i,n,t.getRadius(),e.getRadius());{const t=null!=i?i:n;if(t)return bi(t)}}}function Di(t,e,i){const s="string"==typeof t?t:t.value;return s===Je?i?pi({value:s}):e?Je:Qe:pi({value:s})}function Li(t){return void 0!==t?{h:t.h.value,s:t.s.value,l:t.l.value}:void 0}function Hi(t,e,i){const s={h:{enable:!1,value:t.h},s:{enable:!1,value:t.s},l:{enable:!1,value:t.l}};return e&&(qi(s.h,e.h,i),qi(s.s,e.s,i),qi(s.l,e.l,i)),s}function qi(t,e,i){if(t.enable=e.enable,t.enable){if(t.velocity=y(e.speed)/100*i,e.sync)return;t.status=0,t.velocity*=Math.random(),t.value&&(t.value*=Math.random())}else t.velocity=0}function Fi(t,e,i){t.beginPath(),t.moveTo(e.x,e.y),t.lineTo(i.x,i.y),t.closePath()}function _i(t,e,i,s){t.beginPath(),t.moveTo(e.x,e.y),t.lineTo(i.x,i.y),t.lineTo(s.x,s.y),t.closePath()}function Bi(t,e,i){t.save(),t.fillStyle=null!=i?i:"rgba(0,0,0,0)",t.fillRect(0,0,e.width,e.height),t.restore()}function Vi(t,e){t.clearRect(0,0,e.width,e.height)}function Wi(t,e,i,s,o){t.save(),Fi(t,s,o),t.lineWidth=e,t.strokeStyle=i,t.stroke(),t.restore()}function ji(t,e,i,s){const o=Math.floor(i.getRadius()/e.getRadius()),n=e.getFillColor(),a=i.getFillColor();if(!n||!a)return;const r=e.getPosition(),l=i.getPosition(),c=Ai(n,a,e.getRadius(),i.getRadius()),d=t.createLinearGradient(r.x,r.y,l.x,l.y);return d.addColorStop(0,Oi(n,s)),d.addColorStop(o>1?1:o,Si(c,s)),d.addColorStop(1,Oi(a,s)),d}function Gi(t,e,i,s,o,n){t.save(),Fi(t,i,s),t.strokeStyle=Si(o,n),t.lineWidth=e,t.stroke(),t.restore()}function Ui(t,e,i,s,o,n,a,r,l,c){var d,h,u,p;const v=i.getPosition(),f=i.options.tilt,y=i.options.roll;if(e.save(),f.enable||y.enable){const t=y.enable&&i.roll,s=f.enable&&i.tilt,o=t&&("horizontal"===y.mode||"both"===y.mode),n=t&&("vertical"===y.mode||"both"===y.mode);e.setTransform(o?Math.cos(i.roll.angle):1,s?Math.cos(i.tilt.value)*i.tilt.cosDirection:0,s?Math.sin(i.tilt.value)*i.tilt.sinDirection:0,n?Math.sin(i.roll.angle):1,v.x,v.y)}else e.translate(v.x,v.y);e.beginPath();const m=(null!==(h=null===(d=i.rotate)||void 0===d?void 0:d.value)&&void 0!==h?h:0)+(i.options.rotate.path?i.velocity.angle:0);0!==m&&e.rotate(m),n&&(e.globalCompositeOperation=a);const b=i.shadowColor;c.enable&&b&&(e.shadowBlur=c.blur,e.shadowColor=Si(b),e.shadowOffsetX=c.offset.x,e.shadowOffsetY=c.offset.y),o.fill&&(e.fillStyle=o.fill);const g=i.stroke;e.lineWidth=null!==(u=i.strokeWidth)&&void 0!==u?u:0,o.stroke&&(e.strokeStyle=o.stroke),$i(t,e,i,r,l,s),(null!==(p=null==g?void 0:g.width)&&void 0!==p?p:0)>0&&e.stroke(),i.close&&e.closePath(),i.fill&&e.fill(),e.restore(),e.save(),f.enable&&i.tilt?e.setTransform(1,Math.cos(i.tilt.value)*i.tilt.cosDirection,Math.sin(i.tilt.value)*i.tilt.sinDirection,1,v.x,v.y):e.translate(v.x,v.y),0!==m&&e.rotate(m),n&&(e.globalCompositeOperation=a),Ni(t,e,i,r,l,s),e.restore()}function $i(t,e,i,s,o,n){if(!i.shape)return;const a=t.drawers.get(i.shape);a&&a.draw(e,i,s,o,n,t.retina.pixelRatio)}function Ni(t,e,i,s,o,n){if(!i.shape)return;const a=t.drawers.get(i.shape);(null==a?void 0:a.afterEffect)&&a.afterEffect(e,i,s,o,n,t.retina.pixelRatio)}function Xi(t,e,i){e.draw&&(t.save(),e.draw(t,i),t.restore())}function Yi(t,e,i,s){e.drawParticle&&(t.save(),e.drawParticle(t,i,s),t.restore())}function Ji(t,e,i,s,o,n,a,r,l){if(n<=0)return;const c=e.getPosition();i&&(t.strokeStyle=Oi(i,o)),t.lineWidth=n;const d=a*Math.PI/180;t.beginPath(),t.ellipse(c.x,c.y,s/2,2*s,d,r,l),t.stroke()}function Qi(t,e,i){return{h:t.h,s:t.s,l:t.l+("darken"===e?-1:1)*i}}class Zi{constructor(t){this.container=t,this.size={height:0,width:0},this.context=null,this.generatedCanvas=!1}init(){this.resize(),this.initStyle(),this.initCover(),this.initTrail(),this.initBackground(),this.paint()}loadCanvas(t){var e;this.generatedCanvas&&(null===(e=this.element)||void 0===e||e.remove()),this.generatedCanvas=t.dataset&&Ye in t.dataset?"true"===t.dataset[Ye]:this.generatedCanvas,this.element=t,this.originalStyle=Fe({},this.element.style),this.size.height=t.offsetHeight,this.size.width=t.offsetWidth,this.context=this.element.getContext("2d"),this.container.retina.init(),this.initBackground()}destroy(){var t;this.generatedCanvas&&(null===(t=this.element)||void 0===t||t.remove()),this.draw((t=>{Vi(t,this.size)}))}paint(){const t=this.container.actualOptions;this.draw((e=>{t.backgroundMask.enable&&t.backgroundMask.cover?(Vi(e,this.size),this.paintBase(this.coverColorStyle)):this.paintBase()}))}clear(){const t=this.container.actualOptions,e=t.particles.move.trail;t.backgroundMask.enable?this.paint():e.enable&&e.length>0&&this.trailFillColor?this.paintBase(Si(this.trailFillColor,1/e.length)):this.draw((t=>{Vi(t,this.size)}))}async windowResize(){if(!this.element)return;this.resize();const t=this.container,e=t.updateActualOptions();t.particles.setDensity();for(const[,e]of t.plugins)void 0!==e.resize&&e.resize();e&&await t.refresh()}resize(){if(!this.element)return;const t=this.container,e=t.retina.pixelRatio,i=t.canvas.size,s=this.element.offsetWidth*e,o=this.element.offsetHeight*e;if(o===i.height&&s===i.width&&o===this.element.height&&s===this.element.width)return;const n=Object.assign({},i);this.element.width=i.width=this.element.offsetWidth*e,this.element.height=i.height=this.element.offsetHeight*e,this.container.started&&(this.resizeFactor={width:i.width/n.width,height:i.height/n.height})}drawConnectLine(t,e){this.draw((i=>{var s;const o=this.lineStyle(t,e);if(!o)return;const n=t.getPosition(),a=e.getPosition();Wi(i,null!==(s=t.retina.linksWidth)&&void 0!==s?s:this.container.retina.linksWidth,o,n,a)}))}drawGrabLine(t,e,i,s){const o=this.container;this.draw((n=>{var a;const r=t.getPosition();Gi(n,null!==(a=t.retina.linksWidth)&&void 0!==a?a:o.retina.linksWidth,r,s,e,i)}))}drawParticle(t,e){var i,s,o,n,a,r;if(t.spawning||t.destroyed)return;const l=t.getRadius();if(l<=0)return;const c=t.getFillColor(),d=null!==(i=t.getStrokeColor())&&void 0!==i?i:c;if(!c&&!d)return;let[h,u]=this.getPluginParticleColors(t);h&&u||(h||(h=c||void 0),u||(u=d||void 0));const p=this.container.actualOptions,v=t.options.zIndex,f=(1-t.zIndexFactor)**v.opacityRate,y=null!==(n=null!==(s=t.bubble.opacity)&&void 0!==s?s:null===(o=t.opacity)||void 0===o?void 0:o.value)&&void 0!==n?n:1,m=null!==(r=null===(a=t.stroke)||void 0===a?void 0:a.opacity)&&void 0!==r?r:y,b=y*f,g=m*f,w={fill:h?Oi(h,b):void 0};w.stroke=u?Oi(u,g):w.fill,this.draw((i=>{const s=(1-t.zIndexFactor)**v.sizeRate,o=this.container;for(const e of o.particles.updaters)if(e.beforeDraw&&e.beforeDraw(t),e.getColorStyles){const{fill:s,stroke:o}=e.getColorStyles(t,i,l,b);s&&(w.fill=s),o&&(w.stroke=o)}Ui(o,i,t,e,w,p.backgroundMask.enable,p.backgroundMask.composite,l*s,b,t.options.shadow);for(const e of o.particles.updaters)e.afterDraw&&e.afterDraw(t)}))}drawPlugin(t,e){this.draw((i=>{Xi(i,t,e)}))}drawParticlePlugin(t,e,i){this.draw((s=>{Yi(s,t,e,i)}))}initBackground(){const t=this.container.actualOptions.background,e=this.element,i=null==e?void 0:e.style;if(i){if(t.color){const e=pi(t.color);i.backgroundColor=e?Si(e,t.opacity):""}else i.backgroundColor="";i.backgroundImage=t.image||"",i.backgroundPosition=t.position||"",i.backgroundRepeat=t.repeat||"",i.backgroundSize=t.size||""}}draw(t){if(this.context)return t(this.context)}initCover(){const t=this.container.actualOptions.backgroundMask.cover,e=pi(t.color);if(e){const i={r:e.r,g:e.g,b:e.b,a:t.opacity};this.coverColorStyle=Si(i,i.a)}}initTrail(){const t=this.container.actualOptions,e=pi(t.particles.move.trail.fillColor);if(e){const i=t.particles.move.trail;this.trailFillColor={r:e.r,g:e.g,b:e.b,a:1/i.length}}}getPluginParticleColors(t){let e,i;for(const[,s]of this.container.plugins)if(!e&&s.particleFillColor&&(e=vi(s.particleFillColor(t))),!i&&s.particleStrokeColor&&(i=vi(s.particleStrokeColor(t))),e&&i)break;return[e,i]}initStyle(){const t=this.element,e=this.container.actualOptions;if(!t)return;const i=this.originalStyle;e.fullScreen.enable?(this.originalStyle=Fe({},t.style),t.style.setProperty("position","fixed","important"),t.style.setProperty("z-index",e.fullScreen.zIndex.toString(10),"important"),t.style.setProperty("top","0","important"),t.style.setProperty("left","0","important"),t.style.setProperty("width","100%","important"),t.style.setProperty("height","100%","important")):i&&(t.style.position=i.position,t.style.zIndex=i.zIndex,t.style.top=i.top,t.style.left=i.left,t.style.width=i.width,t.style.height=i.height);for(const i in e.style){if(!i||!e.style)continue;const s=e.style[i];s&&t.style.setProperty(i,s,"important")}}paintBase(t){this.draw((e=>{Bi(e,this.size,t)}))}lineStyle(t,e){return this.draw((i=>{const s=this.container.actualOptions.interactivity.modes.connect;return ji(i,t,e,s.links.opacity)}))}}function Ki(t,e,i,s,o){if(s){let s={passive:!0};"boolean"==typeof o?s.capture=o:void 0!==o&&(s=o),t.addEventListener(e,i,s)}else{const s=o;t.removeEventListener(e,i,s)}}class ts{constructor(t){this.container=t,this.canPush=!0,this.mouseMoveHandler=t=>this.mouseTouchMove(t),this.touchStartHandler=t=>this.mouseTouchMove(t),this.touchMoveHandler=t=>this.mouseTouchMove(t),this.touchEndHandler=()=>this.mouseTouchFinish(),this.mouseLeaveHandler=()=>this.mouseTouchFinish(),this.touchCancelHandler=()=>this.mouseTouchFinish(),this.touchEndClickHandler=t=>this.mouseTouchClick(t),this.mouseUpHandler=t=>this.mouseTouchClick(t),this.mouseDownHandler=()=>this.mouseDown(),this.visibilityChangeHandler=()=>this.handleVisibilityChange(),this.themeChangeHandler=t=>this.handleThemeChange(t),this.oldThemeChangeHandler=t=>this.handleThemeChange(t),this.resizeHandler=()=>this.handleWindowResize()}addListeners(){this.manageListeners(!0)}removeListeners(){this.manageListeners(!1)}manageListeners(t){var e;const i=this.container,s=i.actualOptions,o=s.interactivity.detectsOn;let n=oi;if("window"===o)i.interactivity.element=window,n=ni;else if("parent"===o&&i.canvas.element){const t=i.canvas.element;i.interactivity.element=null!==(e=t.parentElement)&&void 0!==e?e:t.parentNode}else i.interactivity.element=i.canvas.element;const a=!Te()&&"undefined"!=typeof matchMedia&&matchMedia("(prefers-color-scheme: dark)");a&&(void 0!==a.addEventListener?Ki(a,"change",this.themeChangeHandler,t):void 0!==a.addListener&&(t?a.addListener(this.oldThemeChangeHandler):a.removeListener(this.oldThemeChangeHandler)));const r=i.interactivity.element;if(!r)return;const l=r;(s.interactivity.events.onHover.enable||s.interactivity.events.onClick.enable)&&(Ki(r,ei,this.mouseMoveHandler,t),Ki(r,ii,this.touchStartHandler,t),Ki(r,si,this.touchMoveHandler,t),s.interactivity.events.onClick.enable?(Ki(r,Ze,this.touchEndClickHandler,t),Ki(r,ti,this.mouseUpHandler,t),Ki(r,Ke,this.mouseDownHandler,t)):Ki(r,Ze,this.touchEndHandler,t),Ki(r,n,this.mouseLeaveHandler,t),Ki(r,ai,this.touchCancelHandler,t)),i.canvas.element&&(i.canvas.element.style.pointerEvents=l===i.canvas.element?"initial":"none"),s.interactivity.events.resize&&("undefined"!=typeof ResizeObserver?this.resizeObserver&&!t?(i.canvas.element&&this.resizeObserver.unobserve(i.canvas.element),this.resizeObserver.disconnect(),delete this.resizeObserver):!this.resizeObserver&&t&&i.canvas.element&&(this.resizeObserver=new ResizeObserver((t=>{t.find((t=>t.target===i.canvas.element))&&this.handleWindowResize()})),this.resizeObserver.observe(i.canvas.element)):Ki(window,ri,this.resizeHandler,t)),document&&Ki(document,li,this.visibilityChangeHandler,t,!1)}handleWindowResize(){this.resizeTimeout&&(clearTimeout(this.resizeTimeout),delete this.resizeTimeout),this.resizeTimeout=setTimeout((async()=>{var t;return null===(t=this.container.canvas)||void 0===t?void 0:t.windowResize()}),500)}handleVisibilityChange(){const t=this.container,e=t.actualOptions;this.mouseTouchFinish(),e.pauseOnBlur&&((null===document||void 0===document?void 0:document.hidden)?(t.pageHidden=!0,t.pause()):(t.pageHidden=!1,t.getAnimationStatus()?t.play(!0):t.draw(!0)))}mouseDown(){const t=this.container.interactivity;if(t){const e=t.mouse;e.clicking=!0,e.downPosition=e.position}}mouseTouchMove(t){var e,i,s,o,n,a,r;const l=this.container,c=l.actualOptions;if(!(null===(e=l.interactivity)||void 0===e?void 0:e.element))return;let d;l.interactivity.mouse.inside=!0;const h=l.canvas.element;if(t.type.startsWith("mouse")){this.canPush=!0;const e=t;if(l.interactivity.element===window){if(h){const t=h.getBoundingClientRect();d={x:e.clientX-t.left,y:e.clientY-t.top}}}else if("parent"===c.interactivity.detectsOn){const t=e.target,o=e.currentTarget,n=l.canvas.element;if(t&&o&&n){const i=t.getBoundingClientRect(),s=o.getBoundingClientRect(),a=n.getBoundingClientRect();d={x:e.offsetX+2*i.left-(s.left+a.left),y:e.offsetY+2*i.top-(s.top+a.top)}}else d={x:null!==(i=e.offsetX)&&void 0!==i?i:e.clientX,y:null!==(s=e.offsetY)&&void 0!==s?s:e.clientY}}else e.target===l.canvas.element&&(d={x:null!==(o=e.offsetX)&&void 0!==o?o:e.clientX,y:null!==(n=e.offsetY)&&void 0!==n?n:e.clientY})}else{this.canPush="touchmove"!==t.type;const e=t,i=e.touches[e.touches.length-1],s=null==h?void 0:h.getBoundingClientRect();d={x:i.clientX-(null!==(a=null==s?void 0:s.left)&&void 0!==a?a:0),y:i.clientY-(null!==(r=null==s?void 0:s.top)&&void 0!==r?r:0)}}const u=l.retina.pixelRatio;d&&(d.x*=u,d.y*=u),l.interactivity.mouse.position=d,l.interactivity.status=ei}mouseTouchFinish(){const t=this.container.interactivity;if(!t)return;const e=t.mouse;delete e.position,delete e.clickPosition,delete e.downPosition,t.status=oi,e.inside=!1,e.clicking=!1}mouseTouchClick(t){const e=this.container,i=e.actualOptions,s=e.interactivity.mouse;s.inside=!0;let o=!1;const n=s.position;if(n&&i.interactivity.events.onClick.enable){for(const[,t]of e.plugins)if(t.clickPositionValid&&(o=t.clickPositionValid(n),o))break;o||this.doMouseTouchClick(t),s.clicking=!1}}doMouseTouchClick(t){const e=this.container,i=e.actualOptions;if(this.canPush){const t=e.interactivity.mouse.position;if(!t)return;e.interactivity.mouse.clickPosition={x:t.x,y:t.y},e.interactivity.mouse.clickTime=(new Date).getTime();const s=i.interactivity.events.onClick;if(s.mode instanceof Array)for(const t of s.mode)this.handleClickMode(t);else this.handleClickMode(s.mode)}"touchend"===t.type&&setTimeout((()=>this.mouseTouchFinish()),500)}handleThemeChange(t){const e=t.matches?this.container.options.defaultDarkTheme:this.container.options.defaultLightTheme,i=this.container.options.themes.find((t=>t.name===e));i&&i.default.auto&&this.container.loadTheme(e)}handleClickMode(t){this.container.handleClickMode(t)}}class es{constructor(t){this.container=t}async nextFrame(t){var e;try{const i=this.container;if(void 0!==i.lastFrameTime&&t1e3)return void i.draw(!1);if(await i.particles.draw(o),i.duration>0&&i.lifeTime>i.duration)return void i.destroy();i.getAnimationStatus()&&i.draw(!1)}catch(t){console.error("tsParticles error in animation loop",t)}}}var is,ss=function(t,e,i,s,o){if("m"===s)throw new TypeError("Private method is not writable");if("a"===s&&!o)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof e?t!==e||!o:!e.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===s?o.call(t,i):o?o.value=i:e.set(t,i),i},os=function(t,e,i,s){if("a"===i&&!s)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof e?t!==e||!s:!e.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===i?s:"a"===i?s.call(t):s?s.value:e.get(t)};class ns{constructor(t,e){this.container=e,is.set(this,void 0),ss(this,is,t,"f"),this.externalInteractors=[],this.particleInteractors=[],this.init()}init(){const t=os(this,is,"f").plugins.getInteractors(this.container,!0);this.externalInteractors=[],this.particleInteractors=[];for(const e of t)switch(e.type){case 0:this.externalInteractors.push(e);break;case 1:this.particleInteractors.push(e)}}async externalInteract(t){for(const e of this.externalInteractors)e.isEnabled()&&await e.interact(t)}async particlesInteract(t,e){for(const e of this.externalInteractors)e.reset(t);for(const i of this.particleInteractors)i.isEnabled(t)&&await i.interact(t,e)}handleClickMode(t){for(const e of this.externalInteractors)e.handleClickMode&&e.handleClickMode(t)}}is=new WeakMap;class as extends u{constructor(t,e,i){if(super(t,e),"number"!=typeof t&&t)this.z=t.z;else{if(void 0===i)throw new Error("tsParticles - Vector not initialized correctly");this.z=i}}static clone(t){return as.create(t.x,t.y,t.z)}static create(t,e,i){return new as(t,e,i)}static get origin(){return as.create(0,0,0)}add(t){return t instanceof as?as.create(this.x+t.x,this.y+t.y,this.z+t.z):super.add(t)}addTo(t){super.addTo(t),t instanceof as&&(this.z+=t.z)}sub(t){return t instanceof as?as.create(this.x-t.x,this.y-t.y,this.z-t.z):super.sub(t)}subFrom(t){super.subFrom(t),t instanceof as&&(this.z-=t.z)}mult(t){return as.create(this.x*t,this.y*t,this.z*t)}multTo(t){super.multTo(t),this.z*=t}div(t){return as.create(this.x/t,this.y/t,this.z/t)}divTo(t){super.divTo(t),this.z/=t}copy(){return as.clone(this)}setTo(t){super.setTo(t);const e=t;void 0!==e.z&&(this.z=e.z)}}var rs,ls=function(t,e,i,s,o){if("m"===s)throw new TypeError("Private method is not writable");if("a"===s&&!o)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof e?t!==e||!o:!e.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===s?o.call(t,i):o?o.value=i:e.set(t,i),i},cs=function(t,e,i,s){if("a"===i&&!s)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof e?t!==e||!s:!e.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===i?s:"a"===i?s.call(t):s?s.value:e.get(t)};const ds=t=>{(Re(t.outMode,t.checkModes)||Re(t.outMode,t.checkModes))&&(t.coord>t.maxCoord-2*t.radius?t.setCb(-t.radius):t.coord<2*t.radius&&t.setCb(t.radius))};class hs{constructor(t,e,i,s,o,n){var a,r,l,c,d,h,v;this.id=e,this.container=i,this.group=n,rs.set(this,void 0),ls(this,rs,t,"f"),this.fill=!0,this.close=!0,this.lastPathTime=0,this.destroyed=!1,this.unbreakable=!1,this.splitCount=0,this.misplaced=!1,this.retina={maxDistance:{}},this.outType="normal",this.ignoresResizeRatio=!0;const g=i.retina.pixelRatio,x=Xe(i.actualOptions.particles),k=x.shape.type,M=x.reduceDuplicates;if(this.shape=k instanceof Array?De(k,this.id,M):k,null==o?void 0:o.shape){if(o.shape.type){const t=o.shape.type;this.shape=t instanceof Array?De(t,this.id,M):t}const t=new fe;t.load(o.shape),this.shape&&(this.shapeData=this.loadShapeData(t,M))}else this.shapeData=this.loadShapeData(x.shape,M);void 0!==o&&x.load(o),void 0!==(null===(a=this.shapeData)||void 0===a?void 0:a.particles)&&x.load(null===(r=this.shapeData)||void 0===r?void 0:r.particles),this.fill=null!==(c=null===(l=this.shapeData)||void 0===l?void 0:l.fill)&&void 0!==c?c:this.fill,this.close=null!==(h=null===(d=this.shapeData)||void 0===d?void 0:d.close)&&void 0!==h?h:this.close,this.options=x,this.pathDelay=1e3*w(this.options.move.path.delay);const z=y(this.options.zIndex.value);i.retina.initParticle(this);const C=this.options.size,E=C.value;this.size={enable:C.animation.enable,value:y(C.value)*i.retina.pixelRatio,max:b(E)*g,min:m(E)*g,loops:0,maxLoops:y(C.animation.count)};const T=C.animation;if(T.enable){switch(this.size.status=0,T.startValue){case"min":this.size.value=this.size.min,this.size.status=0;break;case"random":this.size.value=f(this.size)*g,this.size.status=Math.random()>=.5?0:1;break;default:this.size.value=this.size.max,this.size.status=1}this.size.velocity=(null!==(v=this.retina.sizeAnimationSpeed)&&void 0!==v?v:i.retina.sizeAnimationSpeed)/100*i.retina.reduceFactor,T.sync||(this.size.velocity*=Math.random())}this.bubble={inRange:!1},this.position=this.calcPosition(i,s,p(z,0,i.zLayers)),this.initialPosition=this.position.copy();const S=i.canvas.size,O=this.options.move.center;switch(this.moveCenter={x:S.width*O.x/100,y:S.height*O.y/100,radius:this.options.move.center.radius},this.direction=P(this.options.move.direction,this.position,this.moveCenter),this.options.move.direction){case"inside":this.outType="inside";break;case"outside":this.outType="outside"}this.initialVelocity=this.calculateVelocity(),this.velocity=this.initialVelocity.copy(),this.moveDecay=1-y(this.options.move.decay);const R=this.options.move.gravity;this.gravity={enable:R.enable,acceleration:y(R.acceleration),inverse:R.inverse},this.offset=u.origin;const A=i.particles;A.needsSort=A.needsSort||A.lastZIndex0,this.shadowColor=pi(this.options.shadow.color);for(const t of i.particles.updaters)t.init&&t.init(this);for(const t of i.particles.movers)t.init&&t.init(this);I&&I.particleInit&&I.particleInit(i,this);for(const[,t]of i.plugins)t.particleCreated&&t.particleCreated(this)}isVisible(){return!this.destroyed&&!this.spawning&&this.isInsideCanvas()}isInsideCanvas(){const t=this.getRadius(),e=this.container.canvas.size;return this.position.x>=-t&&this.position.y>=-t&&this.position.y<=e.height+t&&this.position.x<=e.width+t}draw(t){const e=this.container;for(const[,i]of e.plugins)e.canvas.drawParticlePlugin(i,this,t);e.canvas.drawParticle(this,t)}getPosition(){return{x:this.position.x+this.offset.x,y:this.position.y+this.offset.y,z:this.position.z}}getRadius(){var t;return null!==(t=this.bubble.radius)&&void 0!==t?t:this.size.value}getMass(){return this.getRadius()**2*Math.PI/2}getFillColor(){var t,e;const i=null!==(t=this.bubble.color)&&void 0!==t?t:Li(this.color);if(i&&this.roll&&(this.backColor||this.roll.alter)){const t="both"===this.options.roll.mode?2:1,s="horizontal"===this.options.roll.mode?Math.PI/2:0;if(Math.floor(((null!==(e=this.roll.angle)&&void 0!==e?e:0)+s)/(Math.PI/t))%2){if(this.backColor)return this.backColor;if(this.roll.alter)return Qi(i,this.roll.alter.type,this.roll.alter.value)}}return i}getStrokeColor(){var t,e;return null!==(e=null!==(t=this.bubble.color)&&void 0!==t?t:Li(this.strokeColor))&&void 0!==e?e:this.getFillColor()}destroy(t){if(this.destroyed=!0,this.bubble.inRange=!1,this.unbreakable)return;this.destroyed=!0,this.bubble.inRange=!1;for(const[,e]of this.container.plugins)e.particleDestroyed&&e.particleDestroyed(this,t);if(t)return;"split"===this.options.destroy.mode&&this.split()}reset(){this.opacity&&(this.opacity.loops=0),this.size.loops=0}split(){const t=this.options.destroy.split;if(t.count>=0&&this.splitCount++>t.count)return;const e=w(t.rate);for(let t=0;t{ds({outMode:e,checkModes:["bounce","bounce-horizontal"],coord:c.x,maxCoord:t.canvas.size.width,setCb:t=>c.x+=t,radius:d})},p=e=>{ds({outMode:e,checkModes:["bounce","bounce-vertical"],coord:c.y,maxCoord:t.canvas.size.height,setCb:t=>c.y+=t,radius:d})};return u(null!==(o=h.left)&&void 0!==o?o:h.default),u(null!==(n=h.right)&&void 0!==n?n:h.default),p(null!==(a=h.top)&&void 0!==a?a:h.default),p(null!==(r=h.bottom)&&void 0!==r?r:h.default),this.checkOverlap(c,s)?this.calcPosition(t,void 0,i,s+1):c}checkOverlap(t,e=0){const i=this.options.collisions,s=this.getRadius();if(!i.enable)return!1;const o=i.overlap;if(o.enable)return!1;const n=o.retries;if(n>=0&&e>n)throw new Error("Particle is overlapping and can't be placed");let a=!1;for(const e of this.container.particles.array)if(k(t,e.position)Math.sqrt(n*n+a+a)}if(void 0!==e.size){const t=e.size.width,i=e.size.height,s=Math.pow(n-t,2)+Math.pow(a-i,2);return!(n>r+t||a>r+i)&&(n<=t||a<=i||s<=r*r)}return!1}}class fs extends ps{constructor(t,e,i,s){super(t,e),this.size={height:s,width:i}}contains(t){const e=this.size.width,i=this.size.height,s=this.position;return t.x>=s.x&&t.x<=s.x+e&&t.y>=s.y&&t.y<=s.y+i}intersects(t){const e=t,i=t,s=this.size.width,o=this.size.height,n=this.position,a=t.position;if(void 0!==i.radius)return i.intersects(this);if(!e.size)return!1;const r=e.size,l=r.width,c=r.height;return a.xn.x&&a.yn.y}}class ys extends vs{constructor(t,e,i,s){super(t,e,i),this.canvasSize=s,this.canvasSize=Object.assign({},s)}contains(t){if(super.contains(t))return!0;const e={x:t.x-this.canvasSize.width,y:t.y};if(super.contains(e))return!0;const i={x:t.x-this.canvasSize.width,y:t.y-this.canvasSize.height};if(super.contains(i))return!0;const s={x:t.x,y:t.y-this.canvasSize.height};return super.contains(s)}intersects(t){if(super.intersects(t))return!0;const e=t,i=t,s={x:t.position.x-this.canvasSize.width,y:t.position.y-this.canvasSize.height};if(void 0!==i.radius){const t=new vs(s.x,s.y,2*i.radius);return super.intersects(t)}if(void 0!==e.size){const t=new fs(s.x,s.y,2*e.size.width,2*e.size.height);return super.intersects(t)}return!1}}class ms{constructor(t,e){this.rectangle=t,this.capacity=e,this.points=[],this.divided=!1}insert(t){var e,i,s,o,n;return!!this.rectangle.contains(t.position)&&(this.points.lengthe.particle.getRadius()||a.push(e.particle);return this.divided&&(null===(i=this.northEast)||void 0===i||i.query(t,a),null===(s=this.northWest)||void 0===s||s.query(t,a),null===(o=this.southEast)||void 0===o||o.query(t,a),null===(n=this.southWest)||void 0===n||n.query(t,a)),a}subdivide(){const t=this.rectangle.position.x,e=this.rectangle.position.y,i=this.rectangle.size.width,s=this.rectangle.size.height,o=this.capacity;this.northEast=new ms(new fs(t,e,i/2,s/2),o),this.northWest=new ms(new fs(t+i/2,e,i/2,s/2),o),this.southEast=new ms(new fs(t,e+s/2,i/2,s/2),o),this.southWest=new ms(new fs(t+i/2,e+s/2,i/2,s/2),o),this.divided=!0}}var bs,gs=function(t,e,i,s,o){if("m"===s)throw new TypeError("Private method is not writable");if("a"===s&&!o)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof e?t!==e||!o:!e.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===s?o.call(t,i):o?o.value=i:e.set(t,i),i},ws=function(t,e,i,s){if("a"===i&&!s)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof e?t!==e||!s:!e.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===i?s:"a"===i?s.call(t):s?s.value:e.get(t)};class xs{constructor(t,e){this.container=e,bs.set(this,void 0),gs(this,bs,t,"f"),this.nextId=0,this.array=[],this.zArray=[],this.limit=0,this.needsSort=!1,this.lastZIndex=0,this.freqs={links:new Map,triangles:new Map},this.interactionManager=new ns(ws(this,bs,"f"),e);const i=this.container.canvas.size;this.linksColors=new Map,this.quadTree=new ms(new fs(-i.width/4,-i.height/4,3*i.width/2,3*i.height/2),4),this.movers=ws(this,bs,"f").plugins.getMovers(e,!0),this.updaters=ws(this,bs,"f").plugins.getUpdaters(e,!0)}get count(){return this.array.length}init(){var t;const e=this.container,i=e.actualOptions;this.lastZIndex=0,this.needsSort=!1,this.freqs.links=new Map,this.freqs.triangles=new Map;let s=!1;this.updaters=ws(this,bs,"f").plugins.getUpdaters(e,!0),this.interactionManager.init();for(const[,t]of e.plugins)if(void 0!==t.particlesInitialization&&(s=t.particlesInitialization()),s)break;if(this.addManualParticles(),!s){for(const e in i.particles.groups){const s=i.particles.groups[e];for(let o=this.count,n=0;n<(null===(t=s.number)||void 0===t?void 0:t.value)&&o=0&&t<=this.count))return;let o=0;for(let n=t;oe.position.z-t.position.z||t.id-e.id)),this.lastZIndex=this.zArray[this.zArray.length-1].position.z,this.needsSort=!1);for(const[,i]of e.plugins)e.canvas.drawPlugin(i,t);for(const e of this.zArray)e.draw(t)}clear(){this.array=[],this.zArray=[]}push(t,e,i,s){this.pushing=!0;for(let o=0;o0){const t=this.count+1-o;t>0&&this.removeQuantity(t)}return this.pushParticle(t,e,i)}addSplitParticle(t){const e=t.options.destroy.split,i=Xe(t.options),s=w(e.factor);i.color.load({value:{hsl:t.getFillColor()}}),"number"==typeof i.size.value?i.size.value/=s:(i.size.value.min/=s,i.size.value.max/=s),i.load(e.particles);const o=e.sizeOffset?g(-t.size.value,t.size.value):0,n={x:t.position.x+f(o),y:t.position.y+f(o)};return this.pushParticle(n,i,t.group,(e=>!(e.size.value<.5)&&(e.velocity.length=f(g(t.velocity.length,e.velocity.length)),e.splitCount=t.splitCount+1,e.unbreakable=!0,setTimeout((()=>{e.unbreakable=!1}),500),!0)))}removeQuantity(t,e){this.removeAt(0,t,e)}getLinkFrequency(t,e){const i=g(t.id,e.id),s=`${m(i)}_${b(i)}`;let o=this.freqs.links.get(s);return void 0===o&&(o=Math.random(),this.freqs.links.set(s,o)),o}getTriangleFrequency(t,e,i){let[s,o,n]=[t.id,e.id,i.id];s>o&&([o,s]=[s,o]),o>n&&([n,o]=[o,n]),s>n&&([n,s]=[s,n]);const a=`${s}_${o}_${n}`;let r=this.freqs.triangles.get(a);return void 0===r&&(r=Math.random(),this.freqs.triangles.set(a,r)),r}addManualParticles(){const t=this.container,e=t.actualOptions;for(const i of e.manualParticles)this.addParticle(E({size:t.canvas.size,position:i.position}),i.options)}setDensity(){const t=this.container.actualOptions;for(const e in t.particles.groups)this.applyDensity(t.particles.groups[e],0,e);this.applyDensity(t.particles,t.manualParticles.length)}handleClickMode(t){this.interactionManager.handleClickMode(t)}applyDensity(t,e,i){var s;if(!(null===(s=t.number.density)||void 0===s?void 0:s.enable))return;const o=t.number,n=this.initDensityFactor(o.density),a=o.value,r=o.limit>0?o.limit:a,l=Math.min(a,r)*n+e,c=Math.min(this.count,this.array.filter((t=>t.group===i)).length);this.limit=o.limit*n,cl&&this.removeQuantity(c-l,i)}initDensityFactor(t){const e=this.container;if(!e.canvas.element||!t.enable)return 1;const i=e.canvas.element,s=e.retina.pixelRatio;return i.width*i.height/(t.factor*s**2*t.area)}pushParticle(t,e,i,s){try{const o=new hs(ws(this,bs,"f"),this.nextId,this.container,t,e,i);let n=!0;if(s&&(n=s(o)),!n)return;return this.array.push(o),this.zArray.push(o),this.nextId++,ws(this,bs,"f").dispatchEvent("particleAdded",{container:this.container,data:{particle:o}}),o}catch(t){return void console.warn(`error adding particle: ${t}`)}}}bs=new WeakMap;class ks{constructor(t){this.container=t}init(){const t=this.container,e=t.actualOptions;this.pixelRatio=!e.detectRetina||Te()?1:window.devicePixelRatio;const i=this.container.actualOptions.motion;if(i&&(i.disable||i.reduce.value))if(Te()||"undefined"==typeof matchMedia||!matchMedia)this.reduceFactor=1;else{const e=matchMedia("(prefers-reduced-motion: reduce)");if(e){this.handleMotionChange(e);const i=()=>{this.handleMotionChange(e),t.refresh().catch((()=>{}))};void 0!==e.addEventListener?e.addEventListener("change",i):void 0!==e.addListener&&e.addListener(i)}}else this.reduceFactor=1;const s=this.pixelRatio;if(t.canvas.element){const e=t.canvas.element;t.canvas.size.width=e.offsetWidth*s,t.canvas.size.height=e.offsetHeight*s}const o=e.particles;this.attractDistance=y(o.move.attract.distance)*s,this.linksDistance=o.links.distance*s,this.linksWidth=o.links.width*s,this.sizeAnimationSpeed=y(o.size.animation.speed)*s,this.maxSpeed=y(o.move.gravity.maxSpeed)*s;const n=e.interactivity.modes;this.connectModeDistance=n.connect.distance*s,this.connectModeRadius=n.connect.radius*s,this.grabModeDistance=n.grab.distance*s,this.repulseModeDistance=n.repulse.distance*s,this.bounceModeDistance=n.bounce.distance*s,this.attractModeDistance=n.attract.distance*s,this.slowModeRadius=n.slow.radius*s,this.bubbleModeDistance=n.bubble.distance*s,n.bubble.size&&(this.bubbleModeSize=n.bubble.size*s)}initParticle(t){const e=t.options,i=this.pixelRatio,s=e.move.distance,o=t.retina;o.attractDistance=y(e.move.attract.distance)*i,o.linksDistance=e.links.distance*i,o.linksWidth=e.links.width*i,o.moveDrift=y(e.move.drift)*i,o.moveSpeed=y(e.move.speed)*i,o.sizeAnimationSpeed=y(e.size.animation.speed)*i;const n=o.maxDistance;n.horizontal=void 0!==s.horizontal?s.horizontal*i:void 0,n.vertical=void 0!==s.vertical?s.vertical*i:void 0,o.maxSpeed=y(e.move.gravity.maxSpeed)*i}handleMotionChange(t){const e=this.container.actualOptions;if(t.matches){const t=e.motion;this.reduceFactor=t.disable?0:t.reduce.value?1/t.reduce.factor:1}else this.reduceFactor=1}}var Ps,Ms=function(t,e,i,s,o){if("m"===s)throw new TypeError("Private method is not writable");if("a"===s&&!o)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof e?t!==e||!o:!e.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===s?o.call(t,i):o?o.value=i:e.set(t,i),i},zs=function(t,e,i,s){if("a"===i&&!s)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof e?t!==e||!s:!e.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===i?s:"a"===i?s.call(t):s?s.value:e.get(t)};class Cs{constructor(t,e,i){this.id=e,Ps.set(this,void 0),Ms(this,Ps,t,"f"),this.fpsLimit=120,this.duration=0,this.lifeTime=0,this.firstStart=!0,this.started=!1,this.destroyed=!1,this.paused=!0,this.lastFrameTime=0,this.zLayers=100,this.pageHidden=!1,this._sourceOptions=i,this._initialSourceOptions=i,this.retina=new ks(this),this.canvas=new Zi(this),this.particles=new xs(zs(this,Ps,"f"),this),this.drawer=new es(this),this.pathGenerator={generate:t=>{const e=t.velocity.copy();return e.angle+=e.length*Math.PI/180,e},init:()=>{},update:()=>{}},this.interactivity={mouse:{clicking:!1,inside:!1}},this.plugins=new Map,this.drawers=new Map,this.density=1,this._options=Ne(zs(this,Ps,"f")),this.actualOptions=Ne(zs(this,Ps,"f")),this.eventListeners=new ts(this),"undefined"!=typeof IntersectionObserver&&IntersectionObserver&&(this.intersectionObserver=new IntersectionObserver((t=>this.intersectionManager(t)))),zs(this,Ps,"f").dispatchEvent("containerBuilt",{container:this})}get options(){return this._options}get sourceOptions(){return this._sourceOptions}play(t){const e=this.paused||t;if(!this.firstStart||this.actualOptions.autoPlay){if(this.paused&&(this.paused=!1),e)for(const[,t]of this.plugins)t.play&&t.play();zs(this,Ps,"f").dispatchEvent("containerPlay",{container:this}),this.draw(e||!1)}else this.firstStart=!1}pause(){if(void 0!==this.drawAnimationFrame&&(Oe()(this.drawAnimationFrame),delete this.drawAnimationFrame),!this.paused){for(const[,t]of this.plugins)t.pause&&t.pause();this.pageHidden||(this.paused=!0),zs(this,Ps,"f").dispatchEvent("containerPaused",{container:this})}}draw(t){let e=t;this.drawAnimationFrame=Se()((async t=>{e&&(this.lastFrameTime=void 0,e=!1),await this.drawer.nextFrame(t)}))}getAnimationStatus(){return!this.paused&&!this.pageHidden}setNoise(t,e,i){this.setPath(t,e,i)}setPath(t,e,i){var s,o,n;if(t)if("function"==typeof t)this.pathGenerator.generate=t,e&&(this.pathGenerator.init=e),i&&(this.pathGenerator.update=i);else{const e=this.pathGenerator;this.pathGenerator=t,(s=this.pathGenerator).generate||(s.generate=e.generate),(o=this.pathGenerator).init||(o.init=e.init),(n=this.pathGenerator).update||(n.update=e.update)}}destroy(){this.stop(),this.canvas.destroy();for(const[,t]of this.drawers)t.destroy&&t.destroy(this);for(const t of this.drawers.keys())this.drawers.delete(t);this.destroyed=!0,zs(this,Ps,"f").dispatchEvent("containerDestroyed",{container:this})}exportImg(t){this.exportImage(t)}exportImage(t,e,i){var s;return null===(s=this.canvas.element)||void 0===s?void 0:s.toBlob(t,null!=e?e:"image/png",i)}exportConfiguration(){return JSON.stringify(this.actualOptions,void 0,2)}refresh(){return this.stop(),this.start()}reset(){return this._options=Ne(zs(this,Ps,"f")),this.refresh()}stop(){if(this.started){this.firstStart=!0,this.started=!1,this.eventListeners.removeListeners(),this.pause(),this.particles.clear(),this.canvas.clear(),this.interactivity.element instanceof HTMLElement&&this.intersectionObserver&&this.intersectionObserver.unobserve(this.interactivity.element);for(const[,t]of this.plugins)t.stop&&t.stop();for(const t of this.plugins.keys())this.plugins.delete(t);this.particles.linksColors=new Map,delete this.particles.grabLineColor,delete this.particles.linksColor,this._sourceOptions=this._options,zs(this,Ps,"f").dispatchEvent("containerStopped",{container:this})}}async loadTheme(t){this.currentTheme=t,await this.refresh()}async start(){if(!this.started){await this.init(),this.started=!0,this.eventListeners.addListeners(),this.interactivity.element instanceof HTMLElement&&this.intersectionObserver&&this.intersectionObserver.observe(this.interactivity.element);for(const[,t]of this.plugins)void 0!==t.startAsync?await t.startAsync():void 0!==t.start&&t.start();zs(this,Ps,"f").dispatchEvent("containerStarted",{container:this}),this.play()}}addClickHandler(t){const e=this.interactivity.element;if(!e)return;const i=(e,i,s)=>{if(this.destroyed)return;const o=this.retina.pixelRatio,n={x:i.x*o,y:i.y*o},a=this.particles.quadTree.queryCircle(n,s*o);t(e,a)};let s=!1,o=!1;e.addEventListener("click",(t=>{if(this.destroyed)return;const e=t,s={x:e.offsetX||e.clientX,y:e.offsetY||e.clientY};i(t,s,1)})),e.addEventListener("touchstart",(()=>{this.destroyed||(s=!0,o=!1)})),e.addEventListener("touchmove",(()=>{this.destroyed||(o=!0)})),e.addEventListener("touchend",(t=>{var e,n,a;if(!this.destroyed){if(s&&!o){const s=t;let o=s.touches[s.touches.length-1];if(!o&&(o=s.changedTouches[s.changedTouches.length-1],!o))return;const r=null===(e=this.canvas.element)||void 0===e?void 0:e.getBoundingClientRect(),l={x:o.clientX-(null!==(n=null==r?void 0:r.left)&&void 0!==n?n:0),y:o.clientY-(null!==(a=null==r?void 0:r.top)&&void 0!==a?a:0)};i(t,l,Math.max(o.radiusX,o.radiusY))}s=!1,o=!1}})),e.addEventListener("touchcancel",(()=>{this.destroyed||(s=!1,o=!1)}))}handleClickMode(t){this.particles.handleClickMode(t);for(const[,e]of this.plugins)e.handleClickMode&&e.handleClickMode(t)}updateActualOptions(){this.actualOptions.responsive=[];const t=this.actualOptions.setResponsive(this.canvas.size.width,this.retina.pixelRatio,this._options);return this.actualOptions.setTheme(this.currentTheme),this.responsiveMaxWidth!=t&&(this.responsiveMaxWidth=t,!0)}async init(){const t=zs(this,Ps,"f").plugins.getSupportedShapes();for(const e of t){const t=zs(this,Ps,"f").plugins.getShapeDrawer(e);t&&this.drawers.set(e,t)}this._options=Ne(zs(this,Ps,"f"),this._initialSourceOptions,this.sourceOptions),this.actualOptions=Ne(zs(this,Ps,"f"),this._options),this.retina.init(),this.canvas.init(),this.updateActualOptions(),this.canvas.initBackground(),this.canvas.resize(),this.zLayers=this.actualOptions.zLayers,this.duration=y(this.actualOptions.duration),this.lifeTime=0,this.fpsLimit=this.actualOptions.fpsLimit>0?this.actualOptions.fpsLimit:120;const e=zs(this,Ps,"f").plugins.getAvailablePlugins(this);for(const[t,i]of e)this.plugins.set(t,i);for(const[,t]of this.drawers)t.init&&await t.init(this);for(const[,t]of this.plugins)t.init?t.init(this.actualOptions):void 0!==t.initAsync&&await t.initAsync(this.actualOptions);const i=this.actualOptions.particles.move.path;i.generator&&this.setPath(zs(this,Ps,"f").plugins.getPathGenerator(i.generator)),zs(this,Ps,"f").dispatchEvent("containerInit",{container:this}),this.particles.init(),this.particles.setDensity();for(const[,t]of this.plugins)void 0!==t.particlesSetup&&t.particlesSetup();zs(this,Ps,"f").dispatchEvent("particlesSetup",{container:this})}intersectionManager(t){if(this.actualOptions.pauseOnOutsideViewport)for(const e of t)e.target===this.interactivity.element&&(e.isIntersecting?this.play():this.pause())}}Ps=new WeakMap;var Es,Ts=function(t,e,i,s,o){if("m"===s)throw new TypeError("Private method is not writable");if("a"===s&&!o)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof e?t!==e||!o:!e.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===s?o.call(t,i):o?o.value=i:e.set(t,i),i},Ss=function(t,e,i,s){if("a"===i&&!s)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof e?t!==e||!s:!e.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===i?s:"a"===i?s.call(t):s?s.value:e.get(t)};class Os{constructor(t){Es.set(this,void 0),Ts(this,Es,t,"f")}dom(){return Ss(this,Es,"f").domArray}domItem(t){const e=this.dom(),i=e[t];if(i&&!i.destroyed)return i;e.splice(t,1)}async loadOptions(t){var e,i,s;const o=null!==(e=t.tagId)&&void 0!==e?e:`tsparticles${Math.floor(1e4*Math.random())}`,{options:n,index:a}=t;let r=null!==(i=t.element)&&void 0!==i?i:document.getElementById(o);r||(r=document.createElement("div"),r.id=o,null===(s=document.querySelector("body"))||void 0===s||s.append(r));const l=n instanceof Array?De(n,a):n,c=this.dom(),d=c.findIndex((t=>t.id===o));if(d>=0){const t=this.domItem(d);t&&!t.destroyed&&(t.destroy(),c.splice(d,1))}let h;if("canvas"===r.tagName.toLowerCase())h=r,h.dataset[Ye]="false";else{const t=r.getElementsByTagName("canvas");t.length?(h=t[0],h.dataset[Ye]="false"):(h=document.createElement("canvas"),h.dataset[Ye]="true",h.style.width="100%",h.style.height="100%",r.appendChild(h))}const u=new Cs(Ss(this,Es,"f"),o,l);return d>=0?c.splice(d,0,u):c.push(u),u.canvas.loadCanvas(h),await u.start(),u}async loadRemoteOptions(t){const{url:e,index:i}=t,s=e instanceof Array?De(e,i):e;if(!s)return;const o=await fetch(s);if(!o.ok)return n=o.status,console.error(`Error tsParticles - fetch status: ${n}`),void console.error("Error tsParticles - File config not found");var n;const a=await o.json();return this.loadOptions({tagId:t.tagId,element:t.element,index:i,options:a})}load(t,e,i){const s={index:i};return"string"==typeof t?s.tagId=t:s.options=t,"number"==typeof e?s.index=null!=e?e:s.index:s.options=null!=e?e:s.options,this.loadOptions(s)}async set(t,e,i,s){const o={index:s};return"string"==typeof t?o.tagId=t:o.element=t,e instanceof HTMLElement?o.element=e:o.options=e,"number"==typeof i?o.index=i:o.options=null!=i?i:o.options,this.loadOptions(o)}async loadJSON(t,e,i){let s,o;return"number"==typeof e||void 0===e?s=t:(o=t,s=e),this.loadRemoteOptions({tagId:o,url:s,index:i})}async setJSON(t,e,i,s){let o,n,a,r;return t instanceof HTMLElement?(r=t,o=e,a=i):(n=t,r=e,o=i,a=s),this.loadRemoteOptions({tagId:n,url:o,index:a,element:r})}setOnClickHandler(t){const e=this.dom();if(!e.length)throw new Error("Can only set click handlers after calling tsParticles.load() or tsParticles.loadJSON()");for(const i of e)i.addClickHandler(t)}addEventListener(t,e){Ss(this,Es,"f").eventDispatcher.addEventListener(t,e)}removeEventListener(t,e){Ss(this,Es,"f").eventDispatcher.removeEventListener(t,e)}dispatchEvent(t,e){Ss(this,Es,"f").eventDispatcher.dispatchEvent(t,e)}}Es=new WeakMap;var Rs,As=function(t,e,i,s,o){if("m"===s)throw new TypeError("Private method is not writable");if("a"===s&&!o)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof e?t!==e||!o:!e.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===s?o.call(t,i):o?o.value=i:e.set(t,i),i};class Is{constructor(t){Rs.set(this,void 0),As(this,Rs,t,"f"),this.plugins=[],this.interactorsInitializers=new Map,this.moversInitializers=new Map,this.updatersInitializers=new Map,this.interactors=new Map,this.movers=new Map,this.updaters=new Map,this.presets=new Map,this.drawers=new Map,this.pathGenerators=new Map}getPlugin(t){return this.plugins.find((e=>e.id===t))}addPlugin(t){this.getPlugin(t.id)||this.plugins.push(t)}getAvailablePlugins(t){const e=new Map;for(const i of this.plugins)i.needsPlugin(t.actualOptions)&&e.set(i.id,i.getPlugin(t));return e}loadOptions(t,e){for(const i of this.plugins)i.loadOptions(t,e)}getPreset(t){return this.presets.get(t)}addPreset(t,e,i=!1){!i&&this.getPreset(t)||this.presets.set(t,e)}getShapeDrawer(t){return this.drawers.get(t)}addShapeDrawer(t,e){this.getShapeDrawer(t)||this.drawers.set(t,e)}getSupportedShapes(){return this.drawers.keys()}getPathGenerator(t){return this.pathGenerators.get(t)}addPathGenerator(t,e){this.getPathGenerator(t)||this.pathGenerators.set(t,e)}getInteractors(t,e=!1){let i=this.interactors.get(t);return i&&!e||(i=[...this.interactorsInitializers.values()].map((e=>e(t))),this.interactors.set(t,i)),i}addInteractor(t,e){this.interactorsInitializers.set(t,e)}getUpdaters(t,e=!1){let i=this.updaters.get(t);return i&&!e||(i=[...this.updatersInitializers.values()].map((e=>e(t))),this.updaters.set(t,i)),i}addParticleUpdater(t,e){this.updatersInitializers.set(t,e)}getMovers(t,e=!1){let i=this.movers.get(t);return i&&!e||(i=[...this.moversInitializers.values()].map((e=>e(t))),this.movers.set(t,i)),i}addParticleMover(t,e){this.moversInitializers.set(t,e)}}Rs=new WeakMap;var Ds,Ls,Hs=function(t,e,i,s,o){if("m"===s)throw new TypeError("Private method is not writable");if("a"===s&&!o)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof e?t!==e||!o:!e.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===s?o.call(t,i):o?o.value=i:e.set(t,i),i},qs=function(t,e,i,s){if("a"===i&&!s)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof e?t!==e||!s:!e.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===i?s:"a"===i?s.call(t):s?s.value:e.get(t)};class Fs{constructor(){Ds.set(this,void 0),Ls.set(this,void 0),this.domArray=[],this.eventDispatcher=new h,Hs(this,Ds,!1,"f"),Hs(this,Ls,new Os(this),"f"),this.plugins=new Is(this)}init(){qs(this,Ds,"f")||Hs(this,Ds,!0,"f")}async loadFromArray(t,e,i){return qs(this,Ls,"f").load(t,e,i)}async load(t,e){return qs(this,Ls,"f").load(t,e)}async set(t,e,i){return qs(this,Ls,"f").set(t,e,i)}async loadJSON(t,e,i){return qs(this,Ls,"f").loadJSON(t,e,i)}async setJSON(t,e,i,s){return qs(this,Ls,"f").setJSON(t,e,i,s)}setOnClickHandler(t){qs(this,Ls,"f").setOnClickHandler(t)}dom(){return qs(this,Ls,"f").dom()}domItem(t){return qs(this,Ls,"f").domItem(t)}async refresh(){for(const t of this.dom())await t.refresh()}async addShape(t,e,i,s,o){let n;n="function"==typeof e?{afterEffect:s,destroy:o,draw:e,init:i}:e,this.plugins.addShapeDrawer(t,n),await this.refresh()}async addPreset(t,e,i=!1){this.plugins.addPreset(t,e,i),await this.refresh()}async addPlugin(t){this.plugins.addPlugin(t),await this.refresh()}async addPathGenerator(t,e){this.plugins.addPathGenerator(t,e),await this.refresh()}async addInteractor(t,e){this.plugins.addInteractor(t,e),await this.refresh()}async addMover(t,e){this.plugins.addParticleMover(t,e),await this.refresh()}async addParticleUpdater(t,e){this.plugins.addParticleUpdater(t,e),await this.refresh()}addEventListener(t,e){qs(this,Ls,"f").addEventListener(t,e)}removeEventListener(t,e){qs(this,Ls,"f").removeEventListener(t,e)}dispatchEvent(t,e){qs(this,Ls,"f").dispatchEvent(t,e)}}Ds=new WeakMap,Ls=new WeakMap;class _s{constructor(t){this.container=t,this.type=0}}class Bs{constructor(t){this.container=t,this.type=1}}const Vs=new Fs;Vs.init();class Ws{constructor(){this.radius=0,this.mass=0}load(t){t&&(void 0!==t.mass&&(this.mass=t.mass),void 0!==t.radius&&(this.radius=t.radius))}}class js extends It{constructor(){super(),this.density=5,this.value=50,this.limit=new Ws}load(t){t&&(super.load(t),void 0!==t.density&&(this.density=t.density),"number"==typeof t.limit?this.limit.radius=t.limit:this.limit.load(t.limit))}}class Gs{constructor(){this.color=new A,this.color.value="#000000",this.draggable=!1,this.opacity=1,this.destroy=!0,this.orbits=!1,this.size=new js}load(t){void 0!==t&&(void 0!==t.color&&(this.color=A.create(this.color,t.color)),void 0!==t.draggable&&(this.draggable=t.draggable),this.name=t.name,void 0!==t.opacity&&(this.opacity=t.opacity),void 0!==t.position&&(this.position={},void 0!==t.position.x&&(this.position.x=g(t.position.x)),void 0!==t.position.y&&(this.position.y=g(t.position.y))),void 0!==t.size&&this.size.load(t.size),void 0!==t.destroy&&(this.destroy=t.destroy),void 0!==t.orbits&&(this.orbits=t.orbits))}}class Us{constructor(t,e,i,s){var o,n,a;this.absorbers=t,this.container=e,this.initialPosition=s?u.create(s.x,s.y):void 0,i instanceof Gs?this.options=i:(this.options=new Gs,this.options.load(i)),this.dragging=!1,this.name=this.options.name,this.opacity=this.options.opacity,this.size=y(this.options.size.value)*e.retina.pixelRatio,this.mass=this.size*this.options.size.density*e.retina.reduceFactor;const r=this.options.size.limit;this.limit={radius:r.radius*e.retina.pixelRatio*e.retina.reduceFactor,mass:r.mass},this.color=null!==(o=pi(this.options.color))&&void 0!==o?o:{b:0,g:0,r:0},this.position=null!==(a=null===(n=this.initialPosition)||void 0===n?void 0:n.copy())&&void 0!==a?a:this.calcPosition()}attract(t){const e=this.container,i=this.options;if(i.draggable){const t=e.interactivity.mouse;if(t.clicking&&t.downPosition){k(this.position,t.downPosition)<=this.size&&(this.dragging=!0)}else this.dragging=!1;this.dragging&&t.position&&(this.position.x=t.position.x,this.position.y=t.position.y)}const s=t.getPosition(),{dx:o,dy:n,distance:a}=x(this.position,s),r=u.create(o,n);if(r.length=this.mass/Math.pow(a,2)*e.retina.reduceFactor,at.getRadius()&&a=0?"clockwise":"counter-clockwise");const n=t.absorberOrbit.length,a=t.absorberOrbit.angle,r=t.absorberOrbitDirection;t.velocity.setTo(u.origin);const l={x:"clockwise"===r?Math.cos:Math.sin,y:"clockwise"===r?Math.sin:Math.cos};t.position.x=this.position.x+n*l.x(a),t.position.y=this.position.y+n*l.y(a),t.absorberOrbit.length-=e.length,t.absorberOrbit.angle+=(null!==(i=t.retina.moveSpeed)&&void 0!==i?i:0)*s.retina.pixelRatio/100*s.retina.reduceFactor}else{const i=u.origin;i.length=e.length,i.angle=e.angle,t.velocity.addTo(i)}}}class $s{constructor(t){this.container=t,this.array=[],this.absorbers=[],this.interactivityAbsorbers=[],t.getAbsorber=t=>void 0===t||"number"==typeof t?this.array[t||0]:this.array.find((e=>e.name===t)),t.addAbsorber=(t,e)=>this.addAbsorber(t,e)}init(t){var e,i;if(!t)return;t.absorbers&&(t.absorbers instanceof Array?this.absorbers=t.absorbers.map((t=>{const e=new Gs;return e.load(t),e})):(this.absorbers instanceof Array&&(this.absorbers=new Gs),this.absorbers.load(t.absorbers)));const s=null===(i=null===(e=t.interactivity)||void 0===e?void 0:e.modes)||void 0===i?void 0:i.absorbers;if(s&&(s instanceof Array?this.interactivityAbsorbers=s.map((t=>{const e=new Gs;return e.load(t),e})):(this.interactivityAbsorbers instanceof Array&&(this.interactivityAbsorbers=new Gs),this.interactivityAbsorbers.load(s))),this.absorbers instanceof Array)for(const t of this.absorbers)this.addAbsorber(t);else this.addAbsorber(this.absorbers)}particleUpdate(t){for(const e of this.array)if(e.attract(t),t.destroyed)break}draw(t){for(const e of this.array)t.save(),e.draw(t),t.restore()}stop(){this.array=[]}resize(){for(const t of this.array)t.resize()}handleClickMode(t){const e=this.absorbers,i=this.interactivityAbsorbers;if("absorber"===t){let t;i instanceof Array?i.length>0&&(t=De(i)):t=i;const s=null!=t?t:e instanceof Array?De(e):e,o=this.container.interactivity.mouse.clickPosition;this.addAbsorber(s,o)}}addAbsorber(t,e){const i=new Us(this,this.container,t,e);return this.array.push(i),i}removeAbsorber(t){const e=this.array.indexOf(t);e>=0&&this.array.splice(e,1)}}class Ns{constructor(){this.id="absorbers"}getPlugin(t){return new $s(t)}needsPlugin(t){var e,i,s;if(!t)return!1;const o=t.absorbers;return o instanceof Array?!!o.length:!!o||!(!(null===(s=null===(i=null===(e=t.interactivity)||void 0===e?void 0:e.events)||void 0===i?void 0:i.onClick)||void 0===s?void 0:s.mode)||!Re("absorber",t.interactivity.events.onClick.mode))}loadOptions(t,e){var i,s;if(!this.needsPlugin(t)&&!this.needsPlugin(e))return;const o=t;if(null==e?void 0:e.absorbers)if((null==e?void 0:e.absorbers)instanceof Array)o.absorbers=null==e?void 0:e.absorbers.map((t=>{const e=new Gs;return e.load(t),e}));else{let t=o.absorbers;void 0===(null==t?void 0:t.load)&&(o.absorbers=t=new Gs),t.load(null==e?void 0:e.absorbers)}const n=null===(s=null===(i=null==e?void 0:e.interactivity)||void 0===i?void 0:i.modes)||void 0===s?void 0:s.absorbers;if(n)if(n instanceof Array)o.interactivity.modes.absorbers=n.map((t=>{const e=new Gs;return e.load(t),e}));else{let t=o.interactivity.modes.absorbers;void 0===(null==t?void 0:t.load)&&(o.interactivity.modes.absorbers=t=new Gs),t.load(n)}}}class Xs{randomPosition(t,e,i){const[s,o]=[e.width/2,e.height/2],n=((t,e)=>{const i=Math.random()/4,s=Math.atan(e/t*Math.tan(2*Math.PI*i)),o=Math.random();return o<.25?s:o<.5?Math.PI-s:o<.75?Math.PI+s:-s})(s,o),a=(d=n,(l=s)*(c=o)/Math.sqrt((c*Math.cos(d))**2+(l*Math.sin(d))**2)),r=i?a*Math.sqrt(Math.random()):a;var l,c,d;return{x:t.x+r*Math.cos(n),y:t.y+r*Math.sin(n)}}}class Ys{constructor(){this.wait=!1}load(t){void 0!==t&&(void 0!==t.count&&(this.count=t.count),void 0!==t.delay&&(this.delay=t.delay),void 0!==t.duration&&(this.duration=t.duration),void 0!==t.wait&&(this.wait=t.wait))}}class Js{constructor(){this.quantity=1,this.delay=.1}load(t){void 0!==t&&(void 0!==t.quantity&&(this.quantity=g(t.quantity)),void 0!==t.delay&&(this.delay=g(t.delay)))}}class Qs{constructor(){this.mode="percent",this.height=0,this.width=0}load(t){void 0!==t&&(void 0!==t.mode&&(this.mode=t.mode),void 0!==t.height&&(this.height=t.height),void 0!==t.width&&(this.width=t.width))}}class Zs{constructor(){this.autoPlay=!0,this.fill=!0,this.life=new Ys,this.rate=new Js,this.shape="square",this.startCount=0}load(t){void 0!==t&&(void 0!==t.autoPlay&&(this.autoPlay=t.autoPlay),void 0!==t.size&&(void 0===this.size&&(this.size=new Qs),this.size.load(t.size)),void 0!==t.direction&&(this.direction=t.direction),this.domId=t.domId,void 0!==t.fill&&(this.fill=t.fill),this.life.load(t.life),this.name=t.name,void 0!==t.particles&&(this.particles=Fe({},t.particles)),this.rate.load(t.rate),void 0!==t.shape&&(this.shape=t.shape),void 0!==t.position&&(this.position={},void 0!==t.position.x&&(this.position.x=g(t.position.x)),void 0!==t.position.y&&(this.position.y=g(t.position.y))),void 0!==t.spawnColor&&(void 0===this.spawnColor&&(this.spawnColor=new Mt),this.spawnColor.load(t.spawnColor)),void 0!==t.startCount&&(this.startCount=t.startCount))}}var Ks,to,eo,io=function(t,e,i,s,o){if("m"===s)throw new TypeError("Private method is not writable");if("a"===s&&!o)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof e?t!==e||!o:!e.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===s?o.call(t,i):o?o.value=i:e.set(t,i),i},so=function(t,e,i,s){if("a"===i&&!s)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof e?t!==e||!s:!e.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===i?s:"a"===i?s.call(t):s?s.value:e.get(t)};class oo{constructor(t,e,i,s,o){var n,a,r,l,c,d,h,u;this.emitters=e,this.container=i,Ks.set(this,void 0),to.set(this,void 0),eo.set(this,void 0),io(this,eo,t,"f"),this.currentDuration=0,this.currentEmitDelay=0,this.currentSpawnDelay=0,this.initialPosition=o,s instanceof Zs?this.options=s:(this.options=new Zs,this.options.load(s)),this.spawnDelay=1e3*(null!==(n=this.options.life.delay)&&void 0!==n?n:0)/this.container.retina.reduceFactor,this.position=null!==(a=this.initialPosition)&&void 0!==a?a:this.calcPosition(),this.name=this.options.name,this.shape=null===(r=so(this,eo,"f").emitterShapeManager)||void 0===r?void 0:r.getShape(this.options.shape),this.fill=this.options.fill,io(this,Ks,!this.options.life.wait,"f"),io(this,to,!1,"f");let p=Fe({},this.options.particles);null!=p||(p={}),null!==(l=p.move)&&void 0!==l||(p.move={}),null!==(c=(u=p.move).direction)&&void 0!==c||(u.direction=this.options.direction),this.options.spawnColor&&(this.spawnColor=vi(this.options.spawnColor)),this.paused=!this.options.autoPlay,this.particlesOptions=p,this.size=null!==(d=this.options.size)&&void 0!==d?d:(()=>{const t=new Qs;return t.load({height:0,mode:"percent",width:0}),t})(),this.lifeCount=null!==(h=this.options.life.count)&&void 0!==h?h:-1,this.immortal=this.lifeCount<=0,so(this,eo,"f").dispatchEvent("emitterCreated",{container:i,data:{emitter:this}}),this.play()}externalPlay(){this.paused=!1,this.play()}externalPause(){this.paused=!0,this.pause()}play(){var t;if(!this.paused&&this.container.retina.reduceFactor&&(this.lifeCount>0||this.immortal||!this.options.life.count)&&(so(this,Ks,"f")||this.currentSpawnDelay>=(null!==(t=this.spawnDelay)&&void 0!==t?t:0))){if(void 0===this.emitDelay){const t=y(this.options.rate.delay);this.emitDelay=1e3*t/this.container.retina.reduceFactor}(this.lifeCount>0||this.immortal)&&this.prepareToDie()}}pause(){this.paused||delete this.emitDelay}resize(){const t=this.initialPosition;this.position=t&&Le(t,this.container.canvas.size,u.origin)?t:this.calcPosition()}update(t){var e,i,s;this.paused||(so(this,Ks,"f")&&(io(this,Ks,!1,"f"),this.currentSpawnDelay=null!==(e=this.spawnDelay)&&void 0!==e?e:0,this.currentEmitDelay=null!==(i=this.emitDelay)&&void 0!==i?i:0),so(this,to,"f")||(io(this,to,!0,"f"),this.emitParticles(this.options.startCount)),void 0!==this.duration&&(this.currentDuration+=t.value,this.currentDuration>=this.duration&&(this.pause(),void 0!==this.spawnDelay&&delete this.spawnDelay,this.immortal||this.lifeCount--,this.lifeCount>0||this.immortal?(this.position=this.calcPosition(),this.spawnDelay=1e3*(null!==(s=this.options.life.delay)&&void 0!==s?s:0)/this.container.retina.reduceFactor):this.destroy(),this.currentDuration-=this.duration,delete this.duration)),void 0!==this.spawnDelay&&(this.currentSpawnDelay+=t.value,this.currentSpawnDelay>=this.spawnDelay&&(so(this,eo,"f").dispatchEvent("emitterPlay",{container:this.container}),this.play(),this.currentSpawnDelay-=this.currentSpawnDelay,delete this.spawnDelay)),void 0!==this.emitDelay&&(this.currentEmitDelay+=t.value,this.currentEmitDelay>=this.emitDelay&&(this.emit(),this.currentEmitDelay-=this.emitDelay)))}getPosition(){if(this.options.domId){const t=this.container,e=document.getElementById(this.options.domId);if(e){const i=e.getBoundingClientRect();return{x:(i.x+i.width/2)*t.retina.pixelRatio,y:(i.y+i.height/2)*t.retina.pixelRatio}}}return this.position}getSize(){const t=this.container;if(this.options.domId){const e=document.getElementById(this.options.domId);if(e){const i=e.getBoundingClientRect();return{width:i.width*t.retina.pixelRatio,height:i.height*t.retina.pixelRatio}}}return{width:"percent"===this.size.mode?t.canvas.size.width*this.size.width/100:this.size.width,height:"percent"===this.size.mode?t.canvas.size.height*this.size.height/100:this.size.height}}prepareToDie(){var t;if(this.paused)return;const e=null===(t=this.options.life)||void 0===t?void 0:t.duration;this.container.retina.reduceFactor&&(this.lifeCount>0||this.immortal)&&void 0!==e&&e>0&&(this.duration=1e3*e)}destroy(){this.emitters.removeEmitter(this),so(this,eo,"f").dispatchEvent("emitterDestroyed",{container:this.container,data:{emitter:this}})}calcPosition(){return S({size:this.container.canvas.size,position:this.options.position})}emit(){if(this.paused)return;const t=y(this.options.rate.quantity);this.emitParticles(t)}emitParticles(t){var e,i,s;const o=this.getPosition(),n=this.getSize();for(let a=0;avoid 0===t||"number"==typeof t?this.array[t||0]:this.array.find((e=>e.name===t)),e.addEmitter=(t,e)=>this.addEmitter(t,e),e.removeEmitter=t=>{const i=e.getEmitter(t);i&&this.removeEmitter(i)},e.playEmitter=t=>{const i=e.getEmitter(t);i&&i.externalPlay()},e.pauseEmitter=t=>{const i=e.getEmitter(t);i&&i.externalPause()}}init(t){var e,i;if(!t)return;t.emitters&&(t.emitters instanceof Array?this.emitters=t.emitters.map((t=>{const e=new Zs;return e.load(t),e})):(this.emitters instanceof Array&&(this.emitters=new Zs),this.emitters.load(t.emitters)));const s=null===(i=null===(e=t.interactivity)||void 0===e?void 0:e.modes)||void 0===i?void 0:i.emitters;if(s&&(s instanceof Array?this.interactivityEmitters=s.map((t=>{const e=new Zs;return e.load(t),e})):(this.interactivityEmitters instanceof Array&&(this.interactivityEmitters=new Zs),this.interactivityEmitters.load(s))),this.emitters instanceof Array)for(const t of this.emitters)this.addEmitter(t);else this.addEmitter(this.emitters)}play(){for(const t of this.array)t.play()}pause(){for(const t of this.array)t.pause()}stop(){this.array=[]}update(t){for(const e of this.array)e.update(t)}handleClickMode(t){const e=this.emitters,i=this.interactivityEmitters;if("emitter"===t){let t;i instanceof Array?i.length>0&&(t=De(i)):t=i;const s=null!=t?t:e instanceof Array?De(e):e,o=this.container.interactivity.mouse.clickPosition;this.addEmitter(Fe({},s),o)}}resize(){for(const t of this.array)t.resize()}addEmitter(t,e){const i=new Zs;i.load(t);const s=new oo(ro(this,no,"f"),this,this.container,i,e);return this.array.push(s),s}removeEmitter(t){const e=this.array.indexOf(t);e>=0&&this.array.splice(e,1)}}no=new WeakMap;var co,ho=function(t,e,i,s,o){if("m"===s)throw new TypeError("Private method is not writable");if("a"===s&&!o)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof e?t!==e||!o:!e.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===s?o.call(t,i):o?o.value=i:e.set(t,i),i};const uo=new Map;class po{constructor(t){co.set(this,void 0),ho(this,co,t,"f")}addShape(t,e){this.getShape(t)||uo.set(t,e)}getShape(t){return uo.get(t)}getSupportedShapes(){return uo.keys()}}function vo(t,e){return t+e*(Math.random()-.5)}co=new WeakMap;class fo{randomPosition(t,e,i){if(i)return{x:vo(t.x,e.width),y:vo(t.y,e.height)};{const i=e.width/2,s=e.height/2,o=Math.floor(4*Math.random()),n=2*(Math.random()-.5);switch(o){case 0:return{x:t.x+n*i,y:t.y-s};case 1:return{x:t.x-i,y:t.y+n*s};case 2:return{x:t.x+n*i,y:t.y+s};default:return{x:t.x+i,y:t.y+n*s}}}}}var yo,mo=function(t,e,i,s,o){if("m"===s)throw new TypeError("Private method is not writable");if("a"===s&&!o)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof e?t!==e||!o:!e.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===s?o.call(t,i):o?o.value=i:e.set(t,i),i},bo=function(t,e,i,s){if("a"===i&&!s)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof e?t!==e||!s:!e.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===i?s:"a"===i?s.call(t):s?s.value:e.get(t)};class go{constructor(t){yo.set(this,void 0),mo(this,yo,t,"f"),this.id="emitters"}getPlugin(t){return new lo(bo(this,yo,"f"),t)}needsPlugin(t){var e,i,s;if(void 0===t)return!1;const o=t.emitters;return o instanceof Array&&!!o.length||void 0!==o||!!(null===(s=null===(i=null===(e=t.interactivity)||void 0===e?void 0:e.events)||void 0===i?void 0:i.onClick)||void 0===s?void 0:s.mode)&&Re("emitter",t.interactivity.events.onClick.mode)}loadOptions(t,e){var i,s;if(!this.needsPlugin(t)&&!this.needsPlugin(e))return;const o=t;if(null==e?void 0:e.emitters)if((null==e?void 0:e.emitters)instanceof Array)o.emitters=null==e?void 0:e.emitters.map((t=>{const e=new Zs;return e.load(t),e}));else{let t=o.emitters;void 0===(null==t?void 0:t.load)&&(o.emitters=t=new Zs),t.load(null==e?void 0:e.emitters)}const n=null===(s=null===(i=null==e?void 0:e.interactivity)||void 0===i?void 0:i.modes)||void 0===s?void 0:s.emitters;if(n)if(n instanceof Array)o.interactivity.modes.emitters=n.map((t=>{const e=new Zs;return e.load(t),e}));else{let t=o.interactivity.modes.emitters;void 0===(null==t?void 0:t.load)&&(o.interactivity.modes.emitters=t=new Zs),t.load(n)}}}yo=new WeakMap;class wo extends _s{constructor(t){super(t),this.delay=0}async interact(t){var e,i,s,o;if(!this.container.retina.reduceFactor)return;const n=this.container,a=n.actualOptions.interactivity.modes.trail,r=1e3*a.delay/this.container.retina.reduceFactor;if(this.delay=0&&r<=1};return r<0?(l.x=t.x,l.y=t.y):r>1&&(l.x=e.x,l.y=e.y),l}function Oo(t,e,i){const{dx:s,dy:o}=x(t,e),n=Math.atan2(o,s),a=u.create(Math.sin(n),-Math.cos(n)),r=2*(i.x*a.x+i.y*a.y);a.multTo(r),i.subFrom(a)}var Ro,Ao=function(t,e,i,s,o){if("m"===s)throw new TypeError("Private method is not writable");if("a"===s&&!o)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof e?t!==e||!o:!e.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===s?o.call(t,i):o?o.value=i:e.set(t,i),i},Io=function(t,e,i,s){if("a"===i&&!s)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof e?t!==e||!s:!e.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===i?s:"a"===i?s.call(t):s?s.value:e.get(t)};class Do{constructor(t,e){this.container=t,Ro.set(this,void 0),Ao(this,Ro,e,"f"),this.dimension={height:0,width:0},this.path2DSupported=!!window.Path2D,this.options=new Co,this.polygonMaskMoveRadius=this.options.move.radius*t.retina.pixelRatio}async initAsync(t){this.options.load(null==t?void 0:t.polygon);const e=this.options;this.polygonMaskMoveRadius=e.move.radius*this.container.retina.pixelRatio,e.enable&&await this.initRawData()}resize(){const t=this.container,e=this.options;e.enable&&"none"!==e.type&&(this.redrawTimeout&&clearTimeout(this.redrawTimeout),this.redrawTimeout=window.setTimeout((async()=>{await this.initRawData(!0),await t.particles.redraw()}),250))}stop(){delete this.raw,delete this.paths}particlesInitialization(){const t=this.options;return!(!t.enable||"inline"!==t.type||"one-per-point"!==t.inline.arrangement&&"per-point"!==t.inline.arrangement)&&(this.drawPoints(),!0)}particlePosition(t){var e,i;if(this.options.enable&&(null!==(i=null===(e=this.raw)||void 0===e?void 0:e.length)&&void 0!==i?i:0)>0)return Fe({},t||this.randomPoint())}particleBounce(t,e,i){return this.polygonBounce(t,e,i)}clickPositionValid(t){const e=this.options;return e.enable&&"none"!==e.type&&"inline"!==e.type&&this.checkInsidePolygon(t)}draw(t){var e;if(!(null===(e=this.paths)||void 0===e?void 0:e.length))return;const i=this.options,s=i.draw;if(!i.enable||!s.enable)return;const o=this.raw;for(const e of this.paths){const i=e.path2d,n=this.path2DSupported;t&&(n&&i&&this.offset?To(t,i,s.stroke,this.offset):o&&Eo(t,o,s.stroke))}}polygonBounce(t,e,i){const s=this.options;if(!this.raw||!s.enable||"top"!==i)return!1;if("inside"===s.type||"outside"===s.type){let e,i,s;const o=t.getPosition(),n=t.getRadius();for(let a=0,r=this.raw.length-1;a=e.x&&(i.x=-1),t.position.y>=e.y&&(i.y=-1),t.position.x=e.x+2*n*i.x,t.position.y=e.y+2*n*i.y,t.velocity.mult(-1),!0}}else if("inline"===s.type&&t.initialPosition){if(k(t.initialPosition,t.getPosition())>this.polygonMaskMoveRadius)return t.velocity.x=t.velocity.y/2-t.velocity.x,t.velocity.y=t.velocity.x/2-t.velocity.y,!0}return!1}checkInsidePolygon(t){var e,i;const s=this.container,o=this.options;if(!o.enable||"none"===o.type||"inline"===o.type)return!0;if(!this.raw)throw new Error(di);const n=s.canvas.size,a=null!==(e=null==t?void 0:t.x)&&void 0!==e?e:Math.random()*n.width,r=null!==(i=null==t?void 0:t.y)&&void 0!==i?i:Math.random()*n.height;let l=!1;for(let t=0,e=this.raw.length-1;tr!=s.y>r&&a<(s.x-i.x)*(r-i.y)/(s.y-i.y)+i.x&&(l=!l)}return"inside"===o.type?l:"outside"===o.type&&!l}parseSvgPath(t,e){var i,s,o;const n=null!=e&&e;if(void 0!==this.paths&&!n)return this.raw;const a=this.container,r=this.options,l=(new DOMParser).parseFromString(t,"image/svg+xml"),c=l.getElementsByTagName("svg")[0];let d=c.getElementsByTagName("path");d.length||(d=l.getElementsByTagName("path")),this.paths=[];for(let t=0;tt+e.length),0)/l.particles.number.value;for(const e of this.paths){const i=u*t-h;if(i<=e.length){d=e.element.getPointAtLength(i);break}h+=e.length}return{x:(null!==(i=null==d?void 0:d.x)&&void 0!==i?i:0)*c.scale+(null!==(o=null===(s=this.offset)||void 0===s?void 0:s.x)&&void 0!==o?o:0),y:(null!==(n=null==d?void 0:d.y)&&void 0!==n?n:0)*c.scale+(null!==(r=null===(a=this.offset)||void 0===a?void 0:a.y)&&void 0!==r?r:0)}}getPointByIndex(t){if(!this.raw||!this.raw.length)throw new Error(ci);const e=this.raw[t%this.raw.length];return{x:e.x,y:e.y}}createPath2D(){var t,e;const i=this.options;if(this.path2DSupported&&(null===(t=this.paths)||void 0===t?void 0:t.length))for(const t of this.paths){const s=null===(e=t.element)||void 0===e?void 0:e.getAttribute("d");if(s){const e=new Path2D(s),o=document.createElementNS("http://www.w3.org/2000/svg","svg").createSVGMatrix(),n=new Path2D,a=o.scale(i.scale);n.addPath?(n.addPath(e,a),t.path2d=n):delete t.path2d}else delete t.path2d;!t.path2d&&this.raw&&(t.path2d=new Path2D,t.path2d.moveTo(this.raw[0].x,this.raw[0].y),this.raw.forEach(((e,i)=>{var s;i>0&&(null===(s=t.path2d)||void 0===s||s.lineTo(e.x,e.y))})),t.path2d.closePath())}}async initRawData(t){const e=this.options;if(e.url)this.raw=await this.downloadSvgPath(e.url,t);else if(e.data){const i=e.data;let s;if("string"!=typeof i){const t=i.path instanceof Array?i.path.map((t=>``)).join(""):``;s=`${t}`}else s=i;this.raw=this.parseSvgPath(s,t)}this.createPath2D(),Io(this,Ro,"f").dispatchEvent("polygonMaskLoaded",{container:this.container})}}Ro=new WeakMap;var Lo,Ho=function(t,e,i,s,o){if("m"===s)throw new TypeError("Private method is not writable");if("a"===s&&!o)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof e?t!==e||!o:!e.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===s?o.call(t,i):o?o.value=i:e.set(t,i),i},qo=function(t,e,i,s){if("a"===i&&!s)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof e?t!==e||!s:!e.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===i?s:"a"===i?s.call(t):s?s.value:e.get(t)};class Fo{constructor(t){Lo.set(this,void 0),this.id="polygonMask",Ho(this,Lo,t,"f")}getPlugin(t){return new Do(t,qo(this,Lo,"f"))}needsPlugin(t){var e,i,s;return null!==(i=null===(e=null==t?void 0:t.polygon)||void 0===e?void 0:e.enable)&&void 0!==i?i:void 0!==(null===(s=null==t?void 0:t.polygon)||void 0===s?void 0:s.type)&&"none"!==t.polygon.type}loadOptions(t,e){if(!this.needsPlugin(e))return;const i=t;let s=i.polygon;void 0===(null==s?void 0:s.load)&&(i.polygon=s=new Co),s.load(null==e?void 0:e.polygon)}}Lo=new WeakMap;class _o{init(t){const e=t.options.roll;if(e.enable)if(t.roll={angle:Math.random()*Math.PI*2,speed:y(e.speed)/360},e.backColor)t.backColor=vi(e.backColor);else if(e.darken.enable&&e.enlighten.enable){const i=Math.random()>=.5?"darken":"enlighten";t.roll.alter={type:i,value:y("darken"===i?e.darken.value:e.enlighten.value)}}else e.darken.enable?t.roll.alter={type:"darken",value:y(e.darken.value)}:e.enlighten.enable&&(t.roll.alter={type:"enlighten",value:y(e.enlighten.value)});else t.roll={angle:0,speed:0}}isEnabled(t){const e=t.options.roll;return!t.destroyed&&!t.spawning&&e.enable}update(t,e){this.isEnabled(t)&&function(t,e){const i=t.options.roll;if(!t.roll||!i.enable)return;const s=t.roll.speed*e.factor,o=2*Math.PI;t.roll.angle+=s,t.roll.angle>o&&(t.roll.angle-=o)}(t,e)}}class Bo{constructor(t){this.container=t}init(t){const e=t.options.rotate;t.rotate={enable:e.animation.enable,value:y(e.value)*Math.PI/180};let i=e.direction;if("random"===i){i=Math.floor(2*Math.random())>0?"counter-clockwise":"clockwise"}switch(i){case"counter-clockwise":case"counterClockwise":t.rotate.status=1;break;case"clockwise":t.rotate.status=0}const s=t.options.rotate.animation;s.enable&&(t.rotate.velocity=y(s.speed)/360*this.container.retina.reduceFactor,s.sync||(t.rotate.velocity*=Math.random()))}isEnabled(t){const e=t.options.rotate,i=e.animation;return!t.destroyed&&!t.spawning&&!e.path&&i.enable}update(t,e){this.isEnabled(t)&&function(t,e){var i;const s=t.rotate;if(!s)return;const o=t.options.rotate.animation,n=(null!==(i=s.velocity)&&void 0!==i?i:0)*e.factor,a=2*Math.PI;o.enable&&(0===s.status?(s.value+=n,s.value>a&&(s.value-=a)):(s.value-=n,s.value<0&&(s.value+=a)))}(t,e)}}class Vo{init(t){var e;const i=t.container,s=t.options.move.spin;if(s.enable){const o=null!==(e=s.position)&&void 0!==e?e:{x:50,y:50},n={x:o.x/100*i.canvas.size.width,y:o.y/100*i.canvas.size.height},a=k(t.getPosition(),n),r=y(s.acceleration);t.retina.spinAcceleration=r*i.retina.pixelRatio,t.spin={center:n,direction:t.velocity.x>=0?"clockwise":"counter-clockwise",angle:t.velocity.angle,radius:a,acceleration:t.retina.spinAcceleration}}}isEnabled(t){return!t.destroyed&&t.options.move.enable}move(t,e){var i,s,o,n,a;const r=t.options,l=r.move;if(!l.enable)return;const c=t.container,d=function(t){const e=t.container,i=e.actualOptions;if(!Re("slow",i.interactivity.events.onHover.mode))return 1;const s=t.container.interactivity.mouse.position;if(!s)return 1;const o=k(s,t.getPosition()),n=e.retina.slowModeRadius;return o>n?1:(o/n||0)/i.interactivity.modes.slow.factor}(t),h=(null!==(i=(n=t.retina).moveSpeed)&&void 0!==i?i:n.moveSpeed=y(l.speed)*c.retina.pixelRatio)*c.retina.reduceFactor,u=null!==(s=(a=t.retina).moveDrift)&&void 0!==s?s:a.moveDrift=y(t.options.move.drift)*c.retina.pixelRatio,v=b(r.size.value)*c.retina.pixelRatio,f=h*((l.size?t.getRadius()/v:1)*d*(e.factor||1))/2;!function(t,e){const i=t.options.move.path;if(!i.enable)return;const s=t.container;if(t.lastPathTime<=t.pathDelay)return void(t.lastPathTime+=e.value);const o=s.pathGenerator.generate(t);t.velocity.addTo(o),i.clamp&&(t.velocity.x=p(t.velocity.x,-1,1),t.velocity.y=p(t.velocity.y,-1,1)),t.lastPathTime-=t.pathDelay}(t,e);const m=t.gravity,g=m.enable&&m.inverse?-1:1;m.enable&&f&&(t.velocity.y+=g*(m.acceleration*e.factor)/(60*f)),u&&f&&(t.velocity.x+=u*e.factor/(60*f));const w=t.moveDecay;1!=w&&t.velocity.multTo(w);const P=t.velocity.mult(f),M=null!==(o=t.retina.maxSpeed)&&void 0!==o?o:c.retina.maxSpeed;m.enable&&M>0&&(!m.inverse&&P.y>=0&&P.y>=M||m.inverse&&P.y<=0&&P.y<=-M)&&(P.y=g*M,f&&(t.velocity.y=P.y/f));const z=t.options.zIndex,C=(1-t.zIndexFactor)**z.velocityRate;l.spin.enable?function(t,e){const i=t.container;if(!t.spin)return;const s={x:"clockwise"===t.spin.direction?Math.cos:Math.sin,y:"clockwise"===t.spin.direction?Math.sin:Math.cos};t.position.x=t.spin.center.x+t.spin.radius*s.x(t.spin.angle),t.position.y=t.spin.center.y+t.spin.radius*s.y(t.spin.angle),t.spin.radius+=t.spin.acceleration;const o=Math.max(i.canvas.size.width,i.canvas.size.height);t.spin.radius>o/2?(t.spin.radius=o/2,t.spin.acceleration*=-1):t.spin.radius<0&&(t.spin.radius=0,t.spin.acceleration*=-1),t.spin.angle+=e/100*(1-t.spin.radius/o)}(t,f):(1!=C&&P.multTo(C),t.position.addTo(P),l.vibrate&&(t.position.x+=Math.sin(t.position.x*Math.cos(t.position.y)),t.position.y+=Math.cos(t.position.y*Math.sin(t.position.x)))),function(t){const e=t.initialPosition,{dx:i,dy:s}=x(e,t.position),o=Math.abs(i),n=Math.abs(s),a=t.retina.maxDistance.horizontal,r=t.retina.maxDistance.vertical;if(a||r)if((a&&o>=a||r&&n>=r)&&!t.misplaced)t.misplaced=!!a&&o>a||!!r&&n>r,a&&(t.velocity.x=t.velocity.y/2-t.velocity.x),r&&(t.velocity.y=t.velocity.x/2-t.velocity.y);else if((!a||oe.x&&s.x>0)&&(s.x*=-Math.random()),r&&(i.ye.y&&s.y>0)&&(s.y*=-Math.random())}}(t)}}class Wo{getSidesCount(){return 12}draw(t,e,i){t.arc(0,0,i,0,2*Math.PI,!1)}}function jo(t,e,i,s,o){var n;const a=e;if(!a||!i.enable)return;const r=f(i.offset),l=(null!==(n=e.velocity)&&void 0!==n?n:0)*t.factor+3.6*r;o&&0!==a.status?(a.value-=l,a.value<0&&(a.status=0,a.value+=a.value)):(a.value+=l,o&&a.value>s&&(a.status=1,a.value-=a.value%s)),a.value>s&&(a.value%=s)}class Go{constructor(t){this.container=t}init(t){const e=vi(t.options.color,t.id,t.options.reduceDuplicates);e&&(t.color=Hi(e,t.options.color.animation,this.container.retina.reduceFactor))}isEnabled(t){var e,i,s;const o=t.options.color.animation;return!t.destroyed&&!t.spawning&&(void 0!==(null===(e=t.color)||void 0===e?void 0:e.h.value)&&o.h.enable||void 0!==(null===(i=t.color)||void 0===i?void 0:i.s.value)&&o.s.enable||void 0!==(null===(s=t.color)||void 0===s?void 0:s.l.value)&&o.l.enable)}update(t,e){!function(t,e){var i,s,o;const n=t.options.color.animation;void 0!==(null===(i=t.color)||void 0===i?void 0:i.h)&&jo(e,t.color.h,n.h,360,!1),void 0!==(null===(s=t.color)||void 0===s?void 0:s.s)&&jo(e,t.color.s,n.s,100,!0),void 0!==(null===(o=t.color)||void 0===o?void 0:o.l)&&jo(e,t.color.l,n.l,100,!0)}(t,e)}}class Uo extends _s{constructor(t){super(t),t.attract||(t.attract={particles:[]}),this.handleClickMode=e=>{const i=this.container.actualOptions;if("attract"===e){t.attract||(t.attract={particles:[]}),t.attract.clicking=!0,t.attract.count=0;for(const e of t.attract.particles)e.velocity.setTo(e.initialVelocity);t.attract.particles=[],t.attract.finish=!1,setTimeout((()=>{t.destroyed||(t.attract||(t.attract={particles:[]}),t.attract.clicking=!1)}),1e3*i.interactivity.modes.attract.duration)}}}isEnabled(){const t=this.container,e=t.actualOptions,i=t.interactivity.mouse,s=e.interactivity.events;if(!(i.position&&s.onHover.enable||i.clickPosition&&s.onClick.enable))return!1;const o=s.onHover.mode,n=s.onClick.mode;return Re("attract",o)||Re("attract",n)}reset(){}async interact(){const t=this.container,e=t.actualOptions,i=t.interactivity.status===ei,s=e.interactivity.events,o=s.onHover.enable,n=s.onHover.mode,a=s.onClick.enable,r=s.onClick.mode;i&&o&&Re("attract",n)?this.hoverAttract():a&&Re("attract",r)&&this.clickAttract()}hoverAttract(){const t=this.container,e=t.interactivity.mouse.position;if(!e)return;const i=t.retina.attractModeDistance;this.processAttract(e,i,new vs(e.x,e.y,i))}processAttract(t,e,i){const s=this.container,o=s.actualOptions.interactivity.modes.attract,n=s.particles.quadTree.query(i);for(const i of n){const{dx:s,dy:n,distance:a}=x(i.position,t),r=o.speed*o.factor,l=p(C(1-a/e,o.easing)*r,0,o.maxSpeed),c=u.create(0===a?r:s/a*l,0===a?r:n/a*l);i.position.subFrom(c)}}clickAttract(){const t=this.container;if(t.attract||(t.attract={particles:[]}),t.attract.finish||(t.attract.count||(t.attract.count=0),t.attract.count++,t.attract.count===t.particles.count&&(t.attract.finish=!0)),t.attract.clicking){const e=t.interactivity.mouse.clickPosition;if(!e)return;const i=t.retina.attractModeDistance;this.processAttract(e,i,new vs(e.x,e.y,i))}else!1===t.attract.clicking&&(t.attract.particles=[])}}class $o extends _s{constructor(t){super(t)}isEnabled(){const t=this.container,e=t.actualOptions,i=t.interactivity.mouse,s=e.interactivity.events,o=s.onDiv;return i.position&&s.onHover.enable&&Re("bounce",s.onHover.mode)||_e("bounce",o)}async interact(){const t=this.container,e=t.actualOptions.interactivity.events,i=t.interactivity.status===ei,s=e.onHover.enable,o=e.onHover.mode,n=e.onDiv;i&&s&&Re("bounce",o)?this.processMouseBounce():Be("bounce",n,((t,e)=>this.singleSelectorBounce(t,e)))}reset(){}processMouseBounce(){const t=this.container,e=10*t.retina.pixelRatio,i=t.interactivity.mouse.position,s=t.retina.bounceModeDistance;i&&this.processBounce(i,s,new vs(i.x,i.y,s+e))}singleSelectorBounce(t,e){const i=this.container,s=document.querySelectorAll(t);s.length&&s.forEach((t=>{const s=t,o=i.retina.pixelRatio,n={x:(s.offsetLeft+s.offsetWidth/2)*o,y:(s.offsetTop+s.offsetHeight/2)*o},a=s.offsetWidth/2*o,r=10*o,l="circle"===e.type?new vs(n.x,n.y,a+r):new fs(s.offsetLeft*o-r,s.offsetTop*o-r,s.offsetWidth*o+2*r,s.offsetHeight*o+2*r);this.processBounce(n,a,l)}))}processBounce(t,e,i){const s=this.container.particles.quadTree.query(i);for(const o of s)i instanceof vs?Ge(je(o),{position:t,radius:e,mass:e**2*Math.PI/2,velocity:u.origin,factor:u.origin}):i instanceof fs&&Ue(o,qe(t,e))}}function No(t,e,i,s){if(e>=i){return p(t+(e-i)*s,t,e)}if(e{"bubble"===e&&(t.bubble||(t.bubble={}),t.bubble.clicking=!0)}}isEnabled(){const t=this.container,e=t.actualOptions,i=t.interactivity.mouse,s=e.interactivity.events,o=_e("bubble",s.onDiv);if(!(o||s.onHover.enable&&i.position||s.onClick.enable&&i.clickPosition))return!1;const n=s.onHover.mode,a=s.onClick.mode;return Re("bubble",n)||Re("bubble",a)||o}reset(t,e){t.bubble.inRange&&!e||(delete t.bubble.div,delete t.bubble.opacity,delete t.bubble.radius,delete t.bubble.color)}async interact(){const t=this.container.actualOptions.interactivity.events,e=t.onHover,i=t.onClick,s=e.enable,o=e.mode,n=i.enable,a=i.mode,r=t.onDiv;s&&Re("bubble",o)?this.hoverBubble():n&&Re("bubble",a)?this.clickBubble():Be("bubble",r,((t,e)=>this.singleSelectorHover(t,e)))}singleSelectorHover(t,e){const i=this.container,s=document.querySelectorAll(t);s.length&&s.forEach((t=>{const s=t,o=i.retina.pixelRatio,n={x:(s.offsetLeft+s.offsetWidth/2)*o,y:(s.offsetTop+s.offsetHeight/2)*o},a=s.offsetWidth/2*o,r="circle"===e.type?new vs(n.x,n.y,a):new fs(s.offsetLeft*o,s.offsetTop*o,s.offsetWidth*o,s.offsetHeight*o),l=i.particles.quadTree.query(r);for(const t of l){if(!r.contains(t.getPosition()))continue;t.bubble.inRange=!0;const e=We(i.actualOptions.interactivity.modes.bubble.divs,s);t.bubble.div&&t.bubble.div===s||(this.reset(t,!0),t.bubble.div=s),this.hoverBubbleSize(t,1,e),this.hoverBubbleOpacity(t,1,e),this.hoverBubbleColor(t,1,e)}}))}process(t,e,i,s){const o=this.container,n=s.bubbleObj.optValue;if(void 0===n)return;const a=o.actualOptions.interactivity.modes.bubble.duration,r=o.retina.bubbleModeDistance,l=s.particlesObj.optValue,c=s.bubbleObj.value,d=s.particlesObj.value||0,h=s.type;if(n!==l)if(o.bubble||(o.bubble={}),o.bubble.durationEnd)c&&("size"===h&&delete t.bubble.radius,"opacity"===h&&delete t.bubble.opacity);else if(e<=r){if((null!=c?c:d)!==n){const e=d-i*(d-n)/a;"size"===h&&(t.bubble.radius=e),"opacity"===h&&(t.bubble.opacity=e)}}else"size"===h&&delete t.bubble.radius,"opacity"===h&&delete t.bubble.opacity}clickBubble(){var t,e;const i=this.container,s=i.actualOptions,o=i.interactivity.mouse.clickPosition;if(!o)return;i.bubble||(i.bubble={});const n=i.retina.bubbleModeDistance,a=i.particles.quadTree.queryCircle(o,n);for(const n of a){if(!i.bubble.clicking)continue;n.bubble.inRange=!i.bubble.durationEnd;const a=k(n.getPosition(),o),r=((new Date).getTime()-(i.interactivity.mouse.clickTime||0))/1e3;r>s.interactivity.modes.bubble.duration&&(i.bubble.durationEnd=!0),r>2*s.interactivity.modes.bubble.duration&&(i.bubble.clicking=!1,i.bubble.durationEnd=!1);const l={bubbleObj:{optValue:i.retina.bubbleModeSize,value:n.bubble.radius},particlesObj:{optValue:b(n.options.size.value)*i.retina.pixelRatio,value:n.size.value},type:"size"};this.process(n,a,r,l);const c={bubbleObj:{optValue:s.interactivity.modes.bubble.opacity,value:n.bubble.opacity},particlesObj:{optValue:b(n.options.opacity.value),value:null!==(e=null===(t=n.opacity)||void 0===t?void 0:t.value)&&void 0!==e?e:1},type:"opacity"};this.process(n,a,r,c),i.bubble.durationEnd?delete n.bubble.color:a<=i.retina.bubbleModeDistance?this.hoverBubbleColor(n,a):delete n.bubble.color}}hoverBubble(){const t=this.container,e=t.interactivity.mouse.position;if(void 0===e)return;const i=t.retina.bubbleModeDistance,s=t.particles.quadTree.queryCircle(e,i);for(const o of s){o.bubble.inRange=!0;const s=k(o.getPosition(),e),n=1-s/i;s<=i?n>=0&&t.interactivity.status===ei&&(this.hoverBubbleSize(o,n),this.hoverBubbleOpacity(o,n),this.hoverBubbleColor(o,n)):this.reset(o),t.interactivity.status===oi&&this.reset(o)}}hoverBubbleSize(t,e,i){const s=this.container,o=(null==i?void 0:i.size)?i.size*s.retina.pixelRatio:s.retina.bubbleModeSize;if(void 0===o)return;const n=b(t.options.size.value)*s.retina.pixelRatio,a=No(t.size.value,o,n,e);void 0!==a&&(t.bubble.radius=a)}hoverBubbleOpacity(t,e,i){var s,o,n;const a=this.container.actualOptions,r=null!==(s=null==i?void 0:i.opacity)&&void 0!==s?s:a.interactivity.modes.bubble.opacity;if(!r)return;const l=t.options.opacity.value,c=No(null!==(n=null===(o=t.opacity)||void 0===o?void 0:o.value)&&void 0!==n?n:1,r,b(l),e);void 0!==c&&(t.bubble.opacity=c)}hoverBubbleColor(t,e,i){const s=this.container.actualOptions,o=null!=i?i:s.interactivity.modes.bubble;if(!t.bubble.finalColor){const e=o.color;if(!e)return;const i=e instanceof Array?De(e):e;t.bubble.finalColor=vi(i)}if(t.bubble.finalColor)if(o.mix){t.bubble.color=void 0;const i=t.getFillColor();t.bubble.color=i?fi(Ai(i,t.bubble.finalColor,1-e,e)):t.bubble.finalColor}else t.bubble.color=t.bubble.finalColor}}class Yo extends _s{constructor(t){super(t)}isEnabled(){const t=this.container,e=t.interactivity.mouse,i=t.actualOptions.interactivity.events;return!(!i.onHover.enable||!e.position)&&Re("connect",i.onHover.mode)}reset(){}async interact(){const t=this.container;if(t.actualOptions.interactivity.events.onHover.enable&&"mousemove"===t.interactivity.status){const e=t.interactivity.mouse.position;if(!e)return;const i=Math.abs(t.retina.connectModeRadius),s=t.particles.quadTree.queryCircle(e,i);let o=0;for(const e of s){const i=e.getPosition();for(const n of s.slice(o+1)){const s=n.getPosition(),o=Math.abs(t.retina.connectModeDistance),a=Math.abs(i.x-s.x),r=Math.abs(i.y-s.y);an)continue;const l=s.modes.grab.links,c=l.opacity,d=c-a*c/n;if(d<=0)continue;const h=null!==(t=l.color)&&void 0!==t?t:r.options.links.color;if(!e.particles.grabLineColor){const t=i.interactivity.modes.grab.links;e.particles.grabLineColor=Di(h,t.blink,t.consent)}const u=Ii(r,void 0,e.particles.grabLineColor);if(!u)return;e.canvas.drawGrabLine(r,u,d,o)}}}class Qo extends _s{constructor(t){super(t),this.handleClickMode=t=>{if("pause"!==t)return;const e=this.container;e.getAnimationStatus()?e.pause():e.play()}}isEnabled(){return!0}reset(){}async interact(){}}class Zo extends _s{constructor(t){super(t),this.handleClickMode=t=>{if("push"!==t)return;const e=this.container,i=e.actualOptions,s=i.interactivity.modes.push.quantity;if(s<=0)return;const o=De([void 0,...i.interactivity.modes.push.groups]),n=void 0!==o?e.actualOptions.particles.groups[o]:void 0;e.particles.push(s,e.interactivity.mouse,n,o)}}isEnabled(){return!0}reset(){}async interact(){}}class Ko extends _s{constructor(t){super(t),this.handleClickMode=t=>{if("remove"!==t)return;const e=this.container,i=e.actualOptions.interactivity.modes.remove.quantity;e.particles.removeQuantity(i)}}isEnabled(){return!0}reset(){}async interact(){}}class tn extends _s{constructor(t){super(t),t.repulse||(t.repulse={particles:[]}),this.handleClickMode=e=>{const i=this.container.actualOptions;if("repulse"===e){t.repulse||(t.repulse={particles:[]}),t.repulse.clicking=!0,t.repulse.count=0;for(const e of t.repulse.particles)e.velocity.setTo(e.initialVelocity);t.repulse.particles=[],t.repulse.finish=!1,setTimeout((()=>{t.destroyed||(t.repulse||(t.repulse={particles:[]}),t.repulse.clicking=!1)}),1e3*i.interactivity.modes.repulse.duration)}}}isEnabled(){const t=this.container,e=t.actualOptions,i=t.interactivity.mouse,s=e.interactivity.events,o=_e("repulse",s.onDiv);if(!(o||s.onHover.enable&&i.position||s.onClick.enable&&i.clickPosition))return!1;const n=s.onHover.mode,a=s.onClick.mode;return Re("repulse",n)||Re("repulse",a)||o}reset(){}async interact(){const t=this.container,e=t.actualOptions,i=t.interactivity.status===ei,s=e.interactivity.events,o=s.onHover.enable,n=s.onHover.mode,a=s.onClick.enable,r=s.onClick.mode,l=s.onDiv;i&&o&&Re("repulse",n)?this.hoverRepulse():a&&Re("repulse",r)?this.clickRepulse():Be("repulse",l,((t,e)=>this.singleSelectorRepulse(t,e)))}singleSelectorRepulse(t,e){const i=this.container,s=document.querySelectorAll(t);s.length&&s.forEach((t=>{const s=t,o=i.retina.pixelRatio,n={x:(s.offsetLeft+s.offsetWidth/2)*o,y:(s.offsetTop+s.offsetHeight/2)*o},a=s.offsetWidth/2*o,r="circle"===e.type?new vs(n.x,n.y,a):new fs(s.offsetLeft*o,s.offsetTop*o,s.offsetWidth*o,s.offsetHeight*o),l=We(i.actualOptions.interactivity.modes.repulse.divs,s);this.processRepulse(n,a,r,l)}))}hoverRepulse(){const t=this.container,e=t.interactivity.mouse.position;if(!e)return;const i=t.retina.repulseModeDistance;this.processRepulse(e,i,new vs(e.x,e.y,i))}processRepulse(t,e,i,s){var o;const n=this.container,a=n.particles.quadTree.query(i),r=n.actualOptions.interactivity.modes.repulse;for(const i of a){const{dx:n,dy:a,distance:l}=x(i.position,t),c=(null!==(o=null==s?void 0:s.speed)&&void 0!==o?o:r.speed)*r.factor,d=p(C(1-l/e,r.easing)*c,0,r.maxSpeed),h=u.create(0===l?c:n/l*d,0===l?c:a/l*d);i.position.addTo(h)}}clickRepulse(){const t=this.container;if(t.repulse||(t.repulse={particles:[]}),t.repulse.finish||(t.repulse.count||(t.repulse.count=0),t.repulse.count++,t.repulse.count===t.particles.count&&(t.repulse.finish=!0)),t.repulse.clicking){const e=t.retina.repulseModeDistance,i=Math.pow(e/6,3),s=t.interactivity.mouse.clickPosition;if(void 0===s)return;const o=new vs(s.x,s.y,i),n=t.particles.quadTree.query(o);for(const e of n){const{dx:o,dy:n,distance:a}=x(s,e.position),r=a**2,l=t.actualOptions.interactivity.modes.repulse.speed,c=-i*l/r;if(r<=i){t.repulse.particles.push(e);const i=u.create(o,n);i.length=c,e.velocity.setTo(i)}}}else if(!1===t.repulse.clicking){for(const e of t.repulse.particles)e.velocity.setTo(e.initialVelocity);t.repulse.particles=[]}}}const en=/(#(?:[0-9a-f]{2}){2,4}|(#[0-9a-f]{3})|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d.]+%?\))|currentcolor/gi;async function sn(t){return new Promise((e=>{t.loading=!0;const i=new Image;i.addEventListener("load",(()=>{t.element=i,t.loading=!1,e()})),i.addEventListener("error",(()=>{t.error=!0,t.loading=!1,console.error(`Error tsParticles - loading image: ${t.source}`),e()})),i.src=t.source}))}async function on(t){if("svg"!==t.type)return void await sn(t);t.loading=!0;const e=await fetch(t.source);t.loading=!1,e.ok||(console.error("Error tsParticles - Image not found"),t.error=!0),t.error||(t.svgData=await e.text())}function nn(t,e,i,s){var o,n,a;const r=function(t,e,i){const{svgData:s}=t;if(!s)return"";const o=Oi(e,i);if(s.includes("fill"))return s.replace(en,(()=>o));const n=s.indexOf(">");return`${s.substring(0,n)} fill="${o}"${s.substring(n)}`}(t,i,null!==(n=null===(o=s.opacity)||void 0===o?void 0:o.value)&&void 0!==n?n:1),l=new Blob([r],{type:"image/svg+xml"}),c=URL||window.URL||window.webkitURL||window,d=c.createObjectURL(l),h=new Image,u={data:Object.assign(Object.assign({},t),{svgData:r}),ratio:e.width/e.height,replaceColor:null!==(a=e.replaceColor)&&void 0!==a?a:e.replace_color,source:e.src};return h.addEventListener("load",(()=>{const e=s.image;e&&(e.loaded=!0,t.element=h),c.revokeObjectURL(d)})),h.addEventListener("error",(()=>{c.revokeObjectURL(d);const e=Object.assign(Object.assign({},t),{error:!1,loading:!0});sn(e).then((()=>{const i=s.image;i&&(t.element=e.element,i.loaded=!0)}))})),h.src=d,u}var an,rn=function(t,e,i,s,o){if("m"===s)throw new TypeError("Private method is not writable");if("a"===s&&!o)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof e?t!==e||!o:!e.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===s?o.call(t,i):o?o.value=i:e.set(t,i),i},ln=function(t,e,i,s){if("a"===i&&!s)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof e?t!==e||!s:!e.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===i?s:"a"===i?s.call(t):s?s.value:e.get(t)};class cn{constructor(){an.set(this,void 0),rn(this,an,[],"f")}getSidesCount(){return 12}getImages(t){const e=ln(this,an,"f").find((e=>e.id===t.id));return e||(ln(this,an,"f").push({id:t.id,images:[]}),this.getImages(t))}addImage(t,e){const i=this.getImages(t);null==i||i.images.push(e)}destroy(){rn(this,an,[],"f")}draw(t,e,i,s){var o,n;const a=e.image,r=null===(o=null==a?void 0:a.data)||void 0===o?void 0:o.element;if(!r)return;const l=null!==(n=null==a?void 0:a.ratio)&&void 0!==n?n:1,c={x:-i,y:-i};(null==a?void 0:a.data.svgData)&&(null==a?void 0:a.replaceColor)||(t.globalAlpha=s),t.drawImage(r,c.x,c.y,2*i,2*i/l),(null==a?void 0:a.data.svgData)&&(null==a?void 0:a.replaceColor)||(t.globalAlpha=1)}loadShape(t){var e,i,s;if("image"!==t.shape&&"images"!==t.shape)return;const o=this.getImages(t.container).images,n=t.shapeData,a=o.find((t=>t.source===n.src));let r;if(!a)return void this.loadImageShape(t.container,n).then((()=>{this.loadShape(t)}));if(a.error)return;const l=t.getFillColor();r=a.svgData&&n.replaceColor&&l?nn(a,n,l,t):{data:a,loaded:!0,ratio:n.width/n.height,replaceColor:null!==(e=n.replaceColor)&&void 0!==e?e:n.replace_color,source:n.src},r.ratio||(r.ratio=1);const c={image:r,fill:null!==(i=n.fill)&&void 0!==i?i:t.fill,close:null!==(s=n.close)&&void 0!==s?s:t.close};t.image=c.image,t.fill=c.fill,t.close=c.close}async loadImageShape(t,e){const i=e.src;if(!i)throw new Error("Error tsParticles - No image.src");try{const s={source:i,type:i.substr(i.length-3),error:!1,loading:!0};this.addImage(t,s);const o=e.replaceColor?on:sn;await o(s)}catch(t){throw new Error(`tsParticles error - ${e.src} not found`)}}}an=new WeakMap;class dn{constructor(t){this.container=t}init(){}isEnabled(t){return!t.destroyed}update(t,e){if(!this.isEnabled(t))return;const i=t.life;let s=!1;if(t.spawning){if(i.delayTime+=e.value,!(i.delayTime>=t.life.delay))return;s=!0,t.spawning=!1,i.delayTime=0,i.time=0}if(-1===i.duration)return;if(t.spawning)return;if(s?i.time=0:i.time+=e.value,i.time0&&t.life.count--,0===t.life.count)return void t.destroy();const o=this.container.canvas.size,n=g(0,o.width),a=g(0,o.width);t.position.x=f(n),t.position.y=f(a),t.spawning=!0,i.delayTime=0,i.time=0,t.reset();const r=t.options.life;i.delay=1e3*y(r.delay.value),i.duration=1e3*y(r.duration.value)}}class hn{getSidesCount(){return 1}draw(t,e,i){t.moveTo(-i/2,0),t.lineTo(i/2,0)}}class un{constructor(t){this.container=t}init(t){const e=t.options.opacity;t.opacity={enable:e.animation.enable,max:b(e.value),min:m(e.value),value:y(e.value),loops:0,maxLoops:y(e.animation.count)};const i=e.animation;if(i.enable){t.opacity.status=0;const s=e.value;switch(t.opacity.min=m(s),t.opacity.max=b(s),i.startValue){case"min":t.opacity.value=t.opacity.min,t.opacity.status=0;break;case"random":t.opacity.value=f(t.opacity),t.opacity.status=Math.random()>=.5?0:1;break;default:t.opacity.value=t.opacity.max,t.opacity.status=1}t.opacity.velocity=y(i.speed)/100*this.container.retina.reduceFactor,i.sync||(t.opacity.velocity*=Math.random())}}isEnabled(t){var e,i,s,o;return!t.destroyed&&!t.spawning&&!!t.opacity&&t.opacity.enable&&((null!==(e=t.opacity.maxLoops)&&void 0!==e?e:0)<=0||(null!==(i=t.opacity.maxLoops)&&void 0!==i?i:0)>0&&(null!==(s=t.opacity.loops)&&void 0!==s?s:0)<(null!==(o=t.opacity.maxLoops)&&void 0!==o?o:0))}update(t,e){this.isEnabled(t)&&function(t,e){var i,s,o,n,a;if(!t.opacity)return;const r=t.opacity.min,l=t.opacity.max;if(!(t.destroyed||!t.opacity.enable||(null!==(i=t.opacity.maxLoops)&&void 0!==i?i:0)>0&&(null!==(s=t.opacity.loops)&&void 0!==s?s:0)>(null!==(o=t.opacity.maxLoops)&&void 0!==o?o:0))){switch(t.opacity.status){case 0:t.opacity.value>=l?(t.opacity.status=1,t.opacity.loops||(t.opacity.loops=0),t.opacity.loops++):t.opacity.value+=(null!==(n=t.opacity.velocity)&&void 0!==n?n:0)*e.factor;break;case 1:t.opacity.value<=r?(t.opacity.status=0,t.opacity.loops||(t.opacity.loops=0),t.opacity.loops++):t.opacity.value-=(null!==(a=t.opacity.velocity)&&void 0!==a?a:0)*e.factor}!function(t,e,i,s){switch(t.options.opacity.animation.destroy){case"max":e>=s&&t.destroy();break;case"min":e<=i&&t.destroy()}}(t,t.opacity.value,r,l),t.destroyed||(t.opacity.value=p(t.opacity.value,r,l))}}(t,e)}}class pn{constructor(t){this.container=t,this.modes=["bounce","bounce-vertical","bounce-horizontal","bounceVertical","bounceHorizontal","split"]}update(t,e,i,s){if(!this.modes.includes(s))return;const o=this.container;let n=!1;for(const[,s]of o.plugins)if(void 0!==s.particleBounce&&(n=s.particleBounce(t,i,e)),n)break;if(n)return;const a=t.getPosition(),r=t.offset,l=t.getRadius(),c=qe(a,l),d=o.canvas.size;!function(t){if("bounce"!==t.outMode&&"bounce-horizontal"!==t.outMode&&"bounceHorizontal"!==t.outMode&&"split"!==t.outMode)return;const e=t.particle.velocity.x;let i=!1;if("right"===t.direction&&t.bounds.right>=t.canvasSize.width&&e>0||"left"===t.direction&&t.bounds.left<=0&&e<0){const e=w(t.particle.options.bounce.horizontal);t.particle.velocity.x*=-e,i=!0}if(!i)return;const s=t.offset.x+t.size;t.bounds.right>=t.canvasSize.width?t.particle.position.x=t.canvasSize.width-s:t.bounds.left<=0&&(t.particle.position.x=s),"split"===t.outMode&&t.particle.destroy()}({particle:t,outMode:s,direction:e,bounds:c,canvasSize:d,offset:r,size:l}),function(t){if("bounce"===t.outMode||"bounce-vertical"===t.outMode||"bounceVertical"===t.outMode||"split"===t.outMode){const e=t.particle.velocity.y;let i=!1;if("bottom"===t.direction&&t.bounds.bottom>=t.canvasSize.height&&e>0||"top"===t.direction&&t.bounds.top<=0&&e<0){const e=w(t.particle.options.bounce.vertical);t.particle.velocity.y*=-e,i=!0}if(!i)return;const s=t.offset.y+t.size;t.bounds.bottom>=t.canvasSize.height?t.particle.position.y=t.canvasSize.height-s:t.bounds.top<=0&&(t.particle.position.y=s),"split"===t.outMode&&t.particle.destroy()}}({particle:t,outMode:s,direction:e,bounds:c,canvasSize:d,offset:r,size:l})}}class vn{constructor(t){this.container=t,this.modes=["destroy"]}update(t,e,i,s){if(!this.modes.includes(s))return;const o=this.container;switch(t.outType){case"normal":case"outside":if(Le(t.position,o.canvas.size,u.origin,t.getRadius(),e))return;break;case"inside":{const{dx:e,dy:i}=x(t.position,t.moveCenter),{x:s,y:o}=t.velocity;if(s<0&&e>t.moveCenter.radius||o<0&&i>t.moveCenter.radius||s>=0&&e<-t.moveCenter.radius||o>=0&&i<-t.moveCenter.radius)return;break}}o.particles.remove(t,void 0,!0)}}class fn{constructor(t){this.container=t,this.modes=["none"]}update(t,e,i,s){if(!this.modes.includes(s))return;if(t.options.move.distance.horizontal&&("left"===e||"right"===e)||t.options.move.distance.vertical&&("top"===e||"bottom"===e))return;const o=t.options.move.gravity,n=this.container,a=n.canvas.size,r=t.getRadius();if(o.enable){const i=t.position;(!o.inverse&&i.y>a.height+r&&"bottom"===e||o.inverse&&i.y<-r&&"top"===e)&&n.particles.remove(t)}else{if(t.velocity.y>0&&t.position.y<=a.height+r||t.velocity.y<0&&t.position.y>=-r||t.velocity.x>0&&t.position.x<=a.width+r||t.velocity.x<0&&t.position.x>=-r)return;Le(t.position,n.canvas.size,u.origin,r,e)||n.particles.remove(t)}}}class yn{constructor(t){this.container=t,this.modes=["out"]}update(t,e,i,s){if(!this.modes.includes(s))return;const o=this.container;switch(t.outType){case"inside":{const{x:e,y:i}=t.velocity,s=u.origin;s.length=t.moveCenter.radius,s.angle=t.velocity.angle+Math.PI,s.addTo(u.create(t.moveCenter));const{dx:n,dy:a}=x(t.position,s);if(e<=0&&n>=0||i<=0&&a>=0||e>=0&&n<=0||i>=0&&a<=0)return;t.position.x=Math.floor(f({min:0,max:o.canvas.size.width})),t.position.y=Math.floor(f({min:0,max:o.canvas.size.height}));const{dx:r,dy:l}=x(t.position,t.moveCenter);t.direction=Math.atan2(-l,-r),t.velocity.angle=t.direction;break}default:if(Le(t.position,o.canvas.size,u.origin,t.getRadius(),e))return;switch(t.outType){case"outside":{t.position.x=Math.floor(f({min:-t.moveCenter.radius,max:t.moveCenter.radius}))+t.moveCenter.x,t.position.y=Math.floor(f({min:-t.moveCenter.radius,max:t.moveCenter.radius}))+t.moveCenter.y;const{dx:e,dy:i}=x(t.position,t.moveCenter);t.moveCenter.radius&&(t.direction=Math.atan2(i,e),t.velocity.angle=t.direction);break}case"normal":{const i=t.options.move.warp,s=o.canvas.size,n={bottom:s.height+t.getRadius()+t.offset.y,left:-t.getRadius()-t.offset.x,right:s.width+t.getRadius()+t.offset.x,top:-t.getRadius()-t.offset.y},a=t.getRadius(),r=qe(t.position,a);"right"===e&&r.left>s.width+t.offset.x?(t.position.x=n.left,t.initialPosition.x=t.position.x,i||(t.position.y=Math.random()*s.height,t.initialPosition.y=t.position.y)):"left"===e&&r.right<-t.offset.x&&(t.position.x=n.right,t.initialPosition.x=t.position.x,i||(t.position.y=Math.random()*s.height,t.initialPosition.y=t.position.y)),"bottom"===e&&r.top>s.height+t.offset.y?(i||(t.position.x=Math.random()*s.width,t.initialPosition.x=t.position.x),t.position.y=n.top,t.initialPosition.y=t.position.y):"top"===e&&r.bottom<-t.offset.y&&(i||(t.position.x=Math.random()*s.width,t.initialPosition.x=t.position.x),t.position.y=n.bottom,t.initialPosition.y=t.position.y);break}}}}}class mn{constructor(t){this.container=t,this.updaters=[new pn(t),new vn(t),new yn(t),new fn(t)]}init(){}isEnabled(t){return!t.destroyed&&!t.spawning}update(t,e){var i,s,o,n;const a=t.options.move.outModes;this.updateOutMode(t,e,null!==(i=a.bottom)&&void 0!==i?i:a.default,"bottom"),this.updateOutMode(t,e,null!==(s=a.left)&&void 0!==s?s:a.default,"left"),this.updateOutMode(t,e,null!==(o=a.right)&&void 0!==o?o:a.default,"right"),this.updateOutMode(t,e,null!==(n=a.top)&&void 0!==n?n:a.default,"top")}updateOutMode(t,e,i,s){for(const o of this.updaters)o.update(t,s,e,i)}}class bn{init(){}isEnabled(t){return!Te()&&!t.destroyed&&t.container.actualOptions.interactivity.events.onHover.parallax.enable}move(t){const e=t.container,i=e.actualOptions;if(Te()||!i.interactivity.events.onHover.parallax.enable)return;const s=i.interactivity.events.onHover.parallax.force,o=e.interactivity.mouse.position;if(!o)return;const n=e.canvas.size.width/2,a=e.canvas.size.height/2,r=i.interactivity.events.onHover.parallax.smooth,l=t.getRadius()/s,c=(o.x-n)*l,d=(o.y-a)*l;t.offset.x+=(c-t.offset.x)/r,t.offset.y+=(d-t.offset.y)/r}}class gn extends Bs{constructor(t){super(t)}async interact(t){var e;const i=this.container,s=null!==(e=t.retina.attractDistance)&&void 0!==e?e:i.retina.attractDistance,o=t.getPosition(),n=i.particles.quadTree.queryCircle(o,s);for(const e of n){if(t===e||!e.options.move.attract.enable||e.destroyed||e.spawning)continue;const i=e.getPosition(),{dx:s,dy:n}=x(o,i),a=t.options.move.attract.rotate,r=s/(1e3*a.x),l=n/(1e3*a.y),c=e.size.value/t.size.value,d=1/c;t.velocity.x-=r*c,t.velocity.y-=l*c,e.velocity.x+=r*d,e.velocity.y+=l*d}}isEnabled(t){return t.options.move.attract.enable}reset(){}}function wn(t,e){Ge(je(t),je(e))}function xn(t,e,i,s){switch(t.options.collisions.mode){case"absorb":!function(t,e,i,s){if(void 0===t.getRadius()&&void 0!==e.getRadius())t.destroy();else if(void 0!==t.getRadius()&&void 0===e.getRadius())e.destroy();else if(void 0!==t.getRadius()&&void 0!==e.getRadius())if(t.getRadius()>=e.getRadius()){const o=p(t.getRadius()/e.getRadius(),0,e.getRadius())*i;t.size.value+=o,e.size.value-=o,e.getRadius()<=s&&(e.size.value=0,e.destroy())}else{const o=p(e.getRadius()/t.getRadius(),0,t.getRadius())*i;t.size.value-=o,e.size.value+=o,t.getRadius()<=s&&(t.size.value=0,t.destroy())}}(t,e,i,s);break;case"bounce":wn(t,e);break;case"destroy":!function(t,e){t.unbreakable||e.unbreakable||wn(t,e),void 0===t.getRadius()&&void 0!==e.getRadius()?t.destroy():void 0!==t.getRadius()&&void 0===e.getRadius()?e.destroy():void 0!==t.getRadius()&&void 0!==e.getRadius()&&(t.getRadius()>=e.getRadius()?e.destroy():t.destroy())}(t,e)}}class kn extends Bs{constructor(t){super(t)}isEnabled(t){return t.options.collisions.enable}reset(){}async interact(t){const e=this.container,i=t.getPosition(),s=t.getRadius(),o=e.particles.quadTree.queryCircle(i,2*s);for(const n of o){if(t===n||!n.options.collisions.enable||t.options.collisions.mode!==n.options.collisions.mode||n.destroyed||n.spawning)continue;const o=n.getPosition(),a=n.getRadius();if(Math.abs(Math.round(i.z)-Math.round(o.z))>s+a)continue;k(i,o)>s+a||xn(t,n,e.fpsLimit/1e3,e.retina.pixelRatio)}}}function Pn(t,e,i,s,o){let n=k(t,e);if(!o||n<=i)return n;if(n=k(t,{x:e.x-s.width,y:e.y}),n<=i)return n;if(n=k(t,{x:e.x-s.width,y:e.y-s.height}),n<=i)return n;return n=k(t,{x:e.x,y:e.y-s.height}),n}class Mn extends Bs{constructor(t){super(t)}isEnabled(t){return t.options.links.enable}reset(){}async interact(t){var e;t.links=[];const i=t.getPosition(),s=this.container,o=s.canvas.size;if(i.x<0||i.y<0||i.x>o.width||i.y>o.height)return;const n=t.options.links,a=n.opacity,r=null!==(e=t.retina.linksDistance)&&void 0!==e?e:s.retina.linksDistance,l=n.warp,c=l?new ys(i.x,i.y,r,o):new vs(i.x,i.y,r),d=s.particles.quadTree.query(c);for(const e of d){const s=e.options.links;if(t===e||!s.enable||n.id!==s.id||e.spawning||e.destroyed||-1!==t.links.map((t=>t.destination)).indexOf(e)||-1!==e.links.map((t=>t.destination)).indexOf(t))continue;const c=e.getPosition();if(c.x<0||c.y<0||c.x>o.width||c.y>o.height)continue;const d=Pn(i,c,r,o,l&&s.warp);if(d>r)return;const h=(1-d/r)*a;this.setColor(t),t.links.push({destination:e,opacity:h})}}setColor(t){const e=this.container,i=t.options.links;let s=void 0===i.id?e.particles.linksColor:e.particles.linksColors.get(i.id);if(!s){s=Di(i.color,i.blink,i.consent),void 0===i.id?e.particles.linksColor=s:e.particles.linksColors.set(i.id,s)}}}class zn{constructor(t){this.container=t}particleCreated(t){t.links=[]}particleDestroyed(t){t.links=[]}drawParticle(t,e){const i=e,s=this.container,o=s.particles,n=e.options;if(i.links.length<=0)return;t.save();const a=i.links.filter((t=>s.particles.getLinkFrequency(i,t.destination)<=n.links.frequency));for(const t of a){const e=t.destination;if(n.links.triangles.enable){const r=a.map((t=>t.destination)),l=e.links.filter((t=>s.particles.getLinkFrequency(e,t.destination)<=e.options.links.frequency&&r.indexOf(t.destination)>=0));if(l.length)for(const s of l){const a=s.destination;o.getTriangleFrequency(i,e,a)>n.links.triangles.frequency||this.drawLinkTriangle(i,t,s)}}t.opacity>0&&s.retina.linksWidth>0&&this.drawLinkLine(i,t)}t.restore()}drawLinkTriangle(t,e,i){var s;const o=this.container,n=o.actualOptions,a=e.destination,r=i.destination,l=t.options.links.triangles,c=null!==(s=l.opacity)&&void 0!==s?s:(e.opacity+i.opacity)/2;c<=0||o.canvas.draw((e=>{const i=t.getPosition(),s=a.getPosition(),d=r.getPosition();if(k(i,s)>o.retina.linksDistance||k(d,s)>o.retina.linksDistance||k(d,i)>o.retina.linksDistance)return;let h=pi(l.color);if(!h){const e=t.options.links,i=void 0!==e.id?o.particles.linksColors.get(e.id):o.particles.linksColor;h=Ii(t,a,i)}h&&function(t,e,i,s,o,n,a,r){_i(t,e,i,s),o&&(t.globalCompositeOperation=n),t.fillStyle=Si(a,r),t.fill()}(e,i,s,d,n.backgroundMask.enable,n.backgroundMask.composite,h,c)}))}drawLinkLine(t,e){const i=this.container,s=i.actualOptions,o=e.destination,n=t.getPosition(),a=o.getPosition();let r=e.opacity;i.canvas.draw((e=>{var l,c;let d;const h=t.options.twinkle.lines;if(h.enable){const t=h.frequency,e=pi(h.color);Math.random()new Mn(t)))}(t),await async function(t){const e=new Cn;await t.addPlugin(e)}(t)}class Tn{getSidesCount(t){var e,i;const s=t.shapeData;return null!==(i=null!==(e=null==s?void 0:s.sides)&&void 0!==e?e:null==s?void 0:s.nb_sides)&&void 0!==i?i:5}draw(t,e,i){const s=this.getCenter(e,i),o=this.getSidesData(e,i),n=o.count.numerator*o.count.denominator,a=o.count.numerator/o.count.denominator,r=180*(a-2)/a,l=Math.PI-Math.PI*r/180;if(t){t.beginPath(),t.translate(s.x,s.y),t.moveTo(0,0);for(let e=0;e0&&(null!==(s=t.size.loops)&&void 0!==s?s:0)<(null!==(o=t.size.maxLoops)&&void 0!==o?o:0))}update(t,e){this.isEnabled(t)&&function(t,e){var i,s,o,n;const a=(null!==(i=t.size.velocity)&&void 0!==i?i:0)*e.factor,r=t.size.min,l=t.size.max;if(!(t.destroyed||!t.size.enable||(null!==(s=t.size.maxLoops)&&void 0!==s?s:0)>0&&(null!==(o=t.size.loops)&&void 0!==o?o:0)>(null!==(n=t.size.maxLoops)&&void 0!==n?n:0))){switch(t.size.status){case 0:t.size.value>=l?(t.size.status=1,t.size.loops||(t.size.loops=0),t.size.loops++):t.size.value+=a;break;case 1:t.size.value<=r?(t.size.status=0,t.size.loops||(t.size.loops=0),t.size.loops++):t.size.value-=a}!function(t,e,i,s){switch(t.options.size.animation.destroy){case"max":e>=s&&t.destroy();break;case"min":e<=i&&t.destroy()}}(t,t.size.value,r,l),t.destroyed||(t.size.value=p(t.size.value,r,l))}}(t,e)}}const In=Math.sqrt(2);class Dn{getSidesCount(){return 4}draw(t,e,i){t.rect(-i/In,-i/In,2*i/In,2*i/In)}}class Ln{getSidesCount(t){var e,i;const s=t.shapeData;return null!==(i=null!==(e=null==s?void 0:s.sides)&&void 0!==e?e:null==s?void 0:s.nb_sides)&&void 0!==i?i:5}draw(t,e,i){var s;const o=e.shapeData,n=this.getSidesCount(e),a=null!==(s=null==o?void 0:o.inset)&&void 0!==s?s:2;t.moveTo(0,0-i);for(let e=0;es&&(a.status=1,a.value-=a.value%s)),a.value>s&&(a.value%=s)}class qn{constructor(t){this.container=t}init(t){var e,i;const s=this.container;t.stroke=t.options.stroke instanceof Array?De(t.options.stroke,t.id,t.options.reduceDuplicates):t.options.stroke,t.strokeWidth=t.stroke.width*s.retina.pixelRatio;const o=null!==(e=vi(t.stroke.color))&&void 0!==e?e:t.getFillColor();o&&(t.strokeColor=Hi(o,null===(i=t.stroke.color)||void 0===i?void 0:i.animation,s.retina.reduceFactor))}isEnabled(t){var e,i,s,o;const n=null===(e=t.stroke)||void 0===e?void 0:e.color;return!t.destroyed&&!t.spawning&&!!n&&(void 0!==(null===(i=t.strokeColor)||void 0===i?void 0:i.h.value)&&n.animation.h.enable||void 0!==(null===(s=t.strokeColor)||void 0===s?void 0:s.s.value)&&n.animation.s.enable||void 0!==(null===(o=t.strokeColor)||void 0===o?void 0:o.l.value)&&n.animation.l.enable)}update(t,e){this.isEnabled(t)&&function(t,e){var i,s,o,n,a,r,l,c,d,h;if(!(null===(i=t.stroke)||void 0===i?void 0:i.color))return;const u=t.stroke.color.animation,p=null!==(o=null===(s=t.strokeColor)||void 0===s?void 0:s.h)&&void 0!==o?o:null===(n=t.color)||void 0===n?void 0:n.h;p&&Hn(e,p,u.h,360,!1);const v=null!==(r=null===(a=t.strokeColor)||void 0===a?void 0:a.s)&&void 0!==r?r:null===(l=t.color)||void 0===l?void 0:l.s;v&&Hn(e,v,u.s,100,!0);const f=null!==(d=null===(c=t.strokeColor)||void 0===c?void 0:c.l)&&void 0!==d?d:null===(h=t.color)||void 0===h?void 0:h.l;f&&Hn(e,f,u.l,100,!0)}(t,e)}}const Fn=["text","character","char"];class _n{getSidesCount(){return 12}async init(t){const e=t.actualOptions;if(Fn.find((t=>Re(t,e.particles.shape.type)))){const t=Fn.map((t=>e.particles.shape.options[t])).find((t=>!!t));if(t instanceof Array){const e=[];for(const i of t){const t=i;e.push(Ae(t.font,t.weight))}await Promise.allSettled(e)}else if(void 0!==t){const e=t;await Ae(e.font,e.weight)}}}draw(t,e,i,s){var o,n,a;const r=e.shapeData;if(void 0===r)return;const l=r.value;if(void 0===l)return;const c=e;void 0===c.text&&(c.text=l instanceof Array?De(l,e.randomIndexData):l);const d=c.text,h=null!==(o=r.style)&&void 0!==o?o:"",u=null!==(n=r.weight)&&void 0!==n?n:"400",p=2*Math.round(i),v=null!==(a=r.font)&&void 0!==a?a:"Verdana",f=e.fill,y=d.length*i/2;t.font=`${h} ${u} ${p}px "${v}"`;const m={x:-y,y:i/2};t.globalAlpha=s,f?t.fillText(d,m.x,m.y):t.strokeText(d,m.x,m.y),t.globalAlpha=1}}async function Bn(t){await async function(t){t.addMover("base",(()=>new Vo))}(t),await async function(t){t.addMover("parallax",(()=>new bn))}(t),await async function(t){await t.addInteractor("externalAttract",(t=>new Uo(t)))}(t),await async function(t){await t.addInteractor("externalBounce",(t=>new $o(t)))}(t),await async function(t){await t.addInteractor("externalBubble",(t=>new Xo(t)))}(t),await async function(t){await t.addInteractor("externalConnect",(t=>new Yo(t)))}(t),await async function(t){await t.addInteractor("externalGrab",(t=>new Jo(t)))}(t),await function(t){t.addInteractor("externalPause",(t=>new Qo(t)))}(t),await async function(t){await t.addInteractor("externalPush",(t=>new Zo(t)))}(t),await function(t){t.addInteractor("externalRemove",(t=>new Ko(t)))}(t),await async function(t){await t.addInteractor("externalRepulse",(t=>new tn(t)))}(t),await async function(t){await t.addInteractor("particlesAttract",(t=>new gn(t)))}(t),await async function(t){await t.addInteractor("particlesCollisions",(t=>new kn(t)))}(t),await En(t),await async function(t){await t.addShape("circle",new Wo)}(t),await async function(t){const e=new cn;await t.addShape("image",e),await t.addShape("images",e)}(t),await async function(t){await t.addShape("line",new hn)}(t),await Rn(t),await async function(t){const e=new Dn;await t.addShape("edge",e),await t.addShape("square",e)}(t),await async function(t){await t.addShape("star",new Ln)}(t),await async function(t){const e=new _n;for(const i of Fn)await t.addShape(i,e)}(t),await async function(t){await t.addParticleUpdater("life",(t=>new dn(t)))}(t),await async function(t){await t.addParticleUpdater("opacity",(t=>new un(t)))}(t),await async function(t){await t.addParticleUpdater("size",(()=>new An))}(t),await async function(t){await t.addParticleUpdater("angle",(t=>new Bo(t)))}(t),await async function(t){await t.addParticleUpdater("color",(t=>new Go(t)))}(t),await async function(t){await t.addParticleUpdater("strokeColor",(t=>new qn(t)))}(t),await async function(t){await t.addParticleUpdater("outModes",(t=>new mn(t)))}(t),await(t=>{const e=(e,i)=>t.load(e,i);return e.load=(e,i,s)=>{t.loadJSON(e,i).then((t=>{t&&s(t)})).catch((()=>{s(void 0)}))},e.setOnClickHandler=e=>{t.setOnClickHandler(e)},{particlesJS:e,pJSDom:t.dom()}})(t)}class Vn{constructor(t){this.container=t}init(t){const e=t.options.tilt;t.tilt={enable:e.enable,value:y(e.value)*Math.PI/180,sinDirection:Math.random()>=.5?1:-1,cosDirection:Math.random()>=.5?1:-1};let i=e.direction;if("random"===i){i=Math.floor(2*Math.random())>0?"counter-clockwise":"clockwise"}switch(i){case"counter-clockwise":case"counterClockwise":t.tilt.status=1;break;case"clockwise":t.tilt.status=0}const s=t.options.tilt.animation;s.enable&&(t.tilt.velocity=y(s.speed)/360*this.container.retina.reduceFactor,s.sync||(t.tilt.velocity*=Math.random()))}isEnabled(t){const e=t.options.tilt.animation;return!t.destroyed&&!t.spawning&&e.enable}update(t,e){this.isEnabled(t)&&function(t,e){var i;if(!t.tilt)return;const s=t.options.tilt.animation,o=(null!==(i=t.tilt.velocity)&&void 0!==i?i:0)*e.factor,n=2*Math.PI;s.enable&&(0===t.tilt.status?(t.tilt.value+=o,t.tilt.value>n&&(t.tilt.value-=n)):(t.tilt.value-=o,t.tilt.value<0&&(t.tilt.value+=n)))}(t,e)}}class Wn{getColorStyles(t,e,i,s){const o=t.options.twinkle.particles,n=o.enable&&Math.random()n&&(t.wobble.angle-=n),t.position.x+=o*Math.cos(t.wobble.angle),t.position.y+=o*Math.abs(Math.sin(t.wobble.angle))}(t,e)}}async function Gn(t){await Bn(t),await async function(t){await t.addParticleUpdater("roll",(()=>new _o))}(t),await async function(t){await t.addParticleUpdater("tilt",(t=>new Vn(t)))}(t),await async function(t){await t.addParticleUpdater("twinkle",(()=>new Wn))}(t),await async function(t){await t.addParticleUpdater("wobble",(t=>new jn(t)))}(t),await async function(t){await t.addInteractor("externalTrail",(t=>new wo(t)))}(t),await async function(t){const e=new Ns;await t.addPlugin(e)}(t),await async function(t){t.emitterShapeManager||(t.emitterShapeManager=new po(t)),t.addEmitterShape||(t.addEmitterShape=(e,i)=>{var s;null===(s=t.emitterShapeManager)||void 0===s||s.addShape(e,i)});const e=new go(t);await t.addPlugin(e),t.addEmitterShape("circle",new Xs),t.addEmitterShape("square",new fo)}(t),await async function(t){Te()||"SVGPathSeg"in window||await a.e(939).then(a.t.bind(a,939,23));const e=new Fo(t);await t.addPlugin(e)}(t)}return Gn(Vs),r})())); \ No newline at end of file +/*! For license information please see tsparticles.bundle.min.js.LICENSE.txt */ +!function(t,e){if("object"==typeof exports&&"object"==typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var i=e();for(var s in i)("object"==typeof exports?exports:t)[s]=i[s]}}(this,(()=>(()=>{"use strict";var t={d:(e,i)=>{for(var s in i)t.o(i,s)&&!t.o(e,s)&&Object.defineProperty(e,s,{enumerable:!0,get:i[s]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};t.r(e),t.d(e,{AnimatableColor:()=>fe,AnimationOptions:()=>Mt,AnimationValueWithRandom:()=>Ot,Background:()=>Ti,BackgroundMask:()=>Di,BackgroundMaskCover:()=>Ri,Circle:()=>Ki,ClickEvent:()=>Ii,Collisions:()=>be,CollisionsAbsorb:()=>ve,CollisionsOverlap:()=>me,ColorAnimation:()=>ue,DivEvent:()=>Li,Events:()=>qi,ExternalInteractorBase:()=>li,FullScreen:()=>Ei,HoverEvent:()=>Fi,HslAnimation:()=>pe,HslColorManager:()=>us,Interactivity:()=>Hi,ManualParticle:()=>Ui,Modes:()=>Vi,Move:()=>Oe,MoveAngle:()=>we,MoveAttract:()=>xe,MoveCenter:()=>_e,MoveGravity:()=>ke,MovePath:()=>ze,MoveTrail:()=>Pe,Opacity:()=>Re,OpacityAnimation:()=>Te,Options:()=>ji,OptionsColor:()=>zt,OutModes:()=>Ce,Parallax:()=>Ai,ParticlesBounce:()=>ge,ParticlesBounceFactor:()=>ye,ParticlesDensity:()=>De,ParticlesInteractorBase:()=>fs,ParticlesNumber:()=>Ee,ParticlesOptions:()=>je,Point:()=>Ji,Range:()=>Zi,RangedAnimationOptions:()=>Pt,RangedAnimationValueWithRandom:()=>Tt,Rectangle:()=>Qi,ResizeEvent:()=>Bi,Responsive:()=>Wi,RgbColorManager:()=>ps,Shadow:()=>Ie,Shape:()=>He,Size:()=>We,SizeAnimation:()=>Ue,Spin:()=>Se,Stroke:()=>$e,Theme:()=>Gi,ThemeDefault:()=>$i,ValueWithRandom:()=>St,Vector:()=>m,Vector3d:()=>v,ZIndex:()=>Ge,addColorManager:()=>Ft,addEasing:()=>b,alterHsl:()=>Mi,areBoundsInside:()=>et,arrayRandomIndex:()=>Q,calcExactPositionOrRandomFromSize:()=>q,calcExactPositionOrRandomFromSizeRanged:()=>V,calcPositionFromSize:()=>A,calcPositionOrRandomFromSize:()=>F,calcPositionOrRandomFromSizeRanged:()=>B,calculateBounds:()=>it,circleBounce:()=>lt,circleBounceDataFromParticle:()=>ct,clamp:()=>k,clear:()=>bi,collisionVelocity:()=>L,colorMix:()=>Qt,colorToHsl:()=>Ut,colorToRgb:()=>Ht,deepExtend:()=>st,divMode:()=>rt,divModeExecute:()=>nt,drawLine:()=>vi,drawParticle:()=>wi,drawParticlePlugin:()=>zi,drawPlugin:()=>ki,drawShape:()=>xi,drawShapeAfterEffect:()=>_i,drawTriangle:()=>mi,errorPrefix:()=>f,executeOnSingleOrMultiple:()=>dt,findItemFromSingleOrMultiple:()=>pt,generatedAttribute:()=>i,getDistance:()=>D,getDistances:()=>R,getEasing:()=>w,getHslAnimationFromHsl:()=>ie,getHslFromAnimation:()=>ee,getLinkColor:()=>Kt,getLinkRandomColor:()=>te,getLogger:()=>$,getParticleBaseVelocity:()=>I,getParticleDirectionAngle:()=>E,getPosition:()=>mt,getRandom:()=>_,getRandomRgbColor:()=>Yt,getRangeMax:()=>S,getRangeMin:()=>C,getRangeValue:()=>P,getSize:()=>yt,getStyleFromHsl:()=>Zt,getStyleFromRgb:()=>Jt,getValue:()=>T,hasMatchMedia:()=>N,hslToRgb:()=>Nt,hslaToRgba:()=>Xt,initParticleNumericAnimationValue:()=>ft,isArray:()=>kt,isBoolean:()=>gt,isDivModeEnabled:()=>ot,isFunction:()=>xt,isInArray:()=>J,isNumber:()=>wt,isObject:()=>_t,isPointInside:()=>tt,isSsr:()=>j,isString:()=>bt,itemFromArray:()=>K,itemFromSingleOrMultiple:()=>ut,loadFont:()=>Z,loadFull:()=>fn,loadOptions:()=>Ne,loadParticlesOptions:()=>Xe,loadSlim:()=>on,mix:()=>z,mouseDownEvent:()=>s,mouseLeaveEvent:()=>n,mouseMoveEvent:()=>r,mouseOutEvent:()=>a,mouseUpEvent:()=>o,paintBase:()=>yi,paintImage:()=>gi,parseAlpha:()=>H,randomInRange:()=>M,rangeColorToHsl:()=>Wt,rangeColorToRgb:()=>Vt,rectBounce:()=>ht,resizeEvent:()=>u,rgbToHsl:()=>$t,safeMatchMedia:()=>X,safeMutationObserver:()=>Y,setLogger:()=>W,setRandom:()=>x,setRangeValue:()=>O,singleDivModeExecute:()=>at,stringToAlpha:()=>Gt,stringToRgb:()=>jt,touchCancelEvent:()=>d,touchEndEvent:()=>l,touchMoveEvent:()=>h,touchStartEvent:()=>c,tsParticles:()=>vs,visibilityChangeEvent:()=>p});const i="generated",s="pointerdown",o="pointerup",n="pointerleave",a="pointerout",r="pointermove",c="touchstart",l="touchend",h="touchmove",d="touchcancel",u="resize",p="visibilitychange",f="tsParticles - Error";class v{constructor(t,e,i){if(this._updateFromAngle=(t,e)=>{this.x=Math.cos(t)*e,this.y=Math.sin(t)*e},!wt(t)&&t){this.x=t.x,this.y=t.y;const e=t;this.z=e.z?e.z:0}else{if(void 0===t||void 0===e)throw new Error(`${f} Vector3d not initialized correctly`);this.x=t,this.y=e,this.z=i??0}}static get origin(){return v.create(0,0,0)}get angle(){return Math.atan2(this.y,this.x)}set angle(t){this._updateFromAngle(t,this.length)}get length(){return Math.sqrt(this.getLengthSq())}set length(t){this._updateFromAngle(this.angle,t)}static clone(t){return v.create(t.x,t.y,t.z)}static create(t,e,i){return new v(t,e,i)}add(t){return v.create(this.x+t.x,this.y+t.y,this.z+t.z)}addTo(t){this.x+=t.x,this.y+=t.y,this.z+=t.z}copy(){return v.clone(this)}distanceTo(t){return this.sub(t).length}distanceToSq(t){return this.sub(t).getLengthSq()}div(t){return v.create(this.x/t,this.y/t,this.z/t)}divTo(t){this.x/=t,this.y/=t,this.z/=t}getLengthSq(){return this.x**2+this.y**2}mult(t){return v.create(this.x*t,this.y*t,this.z*t)}multTo(t){this.x*=t,this.y*=t,this.z*=t}normalize(){const t=this.length;0!=t&&this.multTo(1/t)}rotate(t){return v.create(this.x*Math.cos(t)-this.y*Math.sin(t),this.x*Math.sin(t)+this.y*Math.cos(t),0)}setTo(t){this.x=t.x,this.y=t.y;const e=t;this.z=e.z?e.z:0}sub(t){return v.create(this.x-t.x,this.y-t.y,this.z-t.z)}subFrom(t){this.x-=t.x,this.y-=t.y,this.z-=t.z}}class m extends v{constructor(t,e){super(t,e,0)}static get origin(){return m.create(0,0)}static clone(t){return m.create(t.x,t.y)}static create(t,e){return new m(t,e)}}let y=Math.random;const g=new Map;function b(t,e){g.get(t)||g.set(t,e)}function w(t){return g.get(t)||(t=>t)}function x(t=Math.random){y=t}function _(){return k(y(),0,1-1e-16)}function k(t,e,i){return Math.min(Math.max(t,e),i)}function z(t,e,i,s){return Math.floor((t*i+e*s)/(i+s))}function M(t){const e=S(t);let i=C(t);return e===i&&(i=0),_()*(e-i)+i}function P(t){return wt(t)?t:M(t)}function C(t){return wt(t)?t:t.min}function S(t){return wt(t)?t:t.max}function O(t,e){if(t===e||void 0===e&&wt(t))return t;const i=C(t),s=S(t);return void 0!==e?{min:Math.min(i,e),max:Math.max(s,e)}:O(i,s)}function T(t){const e=t.random,{enable:i,minimumValue:s}=gt(e)?{enable:e,minimumValue:0}:e;return P(i?O(t.value,s):t.value)}function R(t,e){const i=t.x-e.x,s=t.y-e.y;return{dx:i,dy:s,distance:Math.sqrt(i**2+s**2)}}function D(t,e){return R(t,e).distance}function E(t,e,i){if(wt(t))return t*Math.PI/180;switch(t){case"top":return-Math.PI/2;case"top-right":return-Math.PI/4;case"right":return 0;case"bottom-right":return Math.PI/4;case"bottom":return Math.PI/2;case"bottom-left":return 3*Math.PI/4;case"left":return Math.PI;case"top-left":return-3*Math.PI/4;case"inside":return Math.atan2(i.y-e.y,i.x-e.x);case"outside":return Math.atan2(e.y-i.y,e.x-i.x);default:return _()*Math.PI*2}}function I(t){const e=m.origin;return e.length=1,e.angle=t,e}function L(t,e,i,s){return m.create(t.x*(i-s)/(i+s)+2*e.x*s/(i+s),t.y)}function A(t){return t.position&&void 0!==t.position.x&&void 0!==t.position.y?{x:t.position.x*t.size.width/100,y:t.position.y*t.size.height/100}:void 0}function F(t){return{x:(t.position?.x??100*_())*t.size.width/100,y:(t.position?.y??100*_())*t.size.height/100}}function B(t){const e={x:void 0!==t.position?.x?P(t.position.x):void 0,y:void 0!==t.position?.y?P(t.position.y):void 0};return F({size:t.size,position:e})}function q(t){return{x:t.position?.x??_()*t.size.width,y:t.position?.y??_()*t.size.height}}function V(t){const e={x:void 0!==t.position?.x?P(t.position.x):void 0,y:void 0!==t.position?.y?P(t.position.y):void 0};return q({size:t.size,position:e})}function H(t){return t?t.endsWith("%")?parseFloat(t)/100:parseFloat(t):1}const U={debug:console.debug,error:console.error,info:console.info,log:console.log,verbose:console.log,warning:console.warn};function W(t){U.debug=t.debug||U.debug,U.error=t.error||U.error,U.info=t.info||U.info,U.log=t.log||U.log,U.verbose=t.verbose||U.verbose,U.warning=t.warning||U.warning}function $(){return U}function G(t){const e={bounced:!1},{pSide:i,pOtherSide:s,rectSide:o,rectOtherSide:n,velocity:a,factor:r}=t;return s.minn.max||s.maxn.max||(i.max>=o.min&&i.max<=(o.max+o.min)/2&&a>0||i.min<=o.max&&i.min>(o.max+o.min)/2&&a<0)&&(e.velocity=a*-r,e.bounced=!0),e}function j(){return"undefined"==typeof window||!window||void 0===window.document||!window.document}function N(){return!j()&&"undefined"!=typeof matchMedia}function X(t){if(N())return matchMedia(t)}function Y(t){if(!j()&&"undefined"!=typeof MutationObserver)return new MutationObserver(t)}function J(t,e){return t===e||kt(e)&&e.indexOf(t)>-1}async function Z(t,e){try{await document.fonts.load(`${e??"400"} 36px '${t??"Verdana"}'`)}catch{}}function Q(t){return Math.floor(_()*t.length)}function K(t,e,i=!0){return t[void 0!==e&&i?e%t.length:Q(t)]}function tt(t,e,i,s,o){return et(it(t,s??0),e,i,o)}function et(t,e,i,s){let o=!0;return s&&"bottom"!==s||(o=t.topi.x),!o||s&&"right"!==s||(o=t.lefti.y),o}function it(t,e){return{bottom:t.y+e,left:t.x-e,right:t.x+e,top:t.y-e}}function st(t,...e){for(const i of e){if(null==i)continue;if(!_t(i)){t=i;continue}const e=Array.isArray(i);!e||!_t(t)&&t&&Array.isArray(t)?e||!_t(t)&&t&&!Array.isArray(t)||(t={}):t=[];for(const e in i){if("__proto__"===e)continue;const s=i[e],o=t;o[e]=_t(s)&&Array.isArray(s)?s.map((t=>st(o[e],t))):st(o[e],s)}}return t}function ot(t,e){return!!pt(e,(e=>e.enable&&J(t,e.mode)))}function nt(t,e,i){dt(e,(e=>{const s=e.mode;e.enable&&J(t,s)&&at(e,i)}))}function at(t,e){dt(t.selectors,(i=>{e(i,t)}))}function rt(t,e){if(e&&t)return pt(t,(t=>function(t,e){const i=dt(e,(e=>t.matches(e)));return kt(i)?i.some((t=>t)):i}(e,t.selectors)))}function ct(t){return{position:t.getPosition(),radius:t.getRadius(),mass:t.getMass(),velocity:t.velocity,factor:m.create(T(t.options.bounce.horizontal),T(t.options.bounce.vertical))}}function lt(t,e){const{x:i,y:s}=t.velocity.sub(e.velocity),[o,n]=[t.position,e.position],{dx:a,dy:r}=R(n,o);if(i*a+s*r<0)return;const c=-Math.atan2(r,a),l=t.mass,h=e.mass,d=t.velocity.rotate(c),u=e.velocity.rotate(c),p=L(d,u,l,h),f=L(u,d,l,h),v=p.rotate(-c),m=f.rotate(-c);t.velocity.x=v.x*t.factor.x,t.velocity.y=v.y*t.factor.y,e.velocity.x=m.x*e.factor.x,e.velocity.y=m.y*e.factor.y}function ht(t,e){const i=it(t.getPosition(),t.getRadius()),s=G({pSide:{min:i.left,max:i.right},pOtherSide:{min:i.top,max:i.bottom},rectSide:{min:e.left,max:e.right},rectOtherSide:{min:e.top,max:e.bottom},velocity:t.velocity.x,factor:T(t.options.bounce.horizontal)});s.bounced&&(void 0!==s.velocity&&(t.velocity.x=s.velocity),void 0!==s.position&&(t.position.x=s.position));const o=G({pSide:{min:i.top,max:i.bottom},pOtherSide:{min:i.left,max:i.right},rectSide:{min:e.top,max:e.bottom},rectOtherSide:{min:e.left,max:e.right},velocity:t.velocity.y,factor:T(t.options.bounce.vertical)});o.bounced&&(void 0!==o.velocity&&(t.velocity.y=o.velocity),void 0!==o.position&&(t.position.y=o.position))}function dt(t,e){return kt(t)?t.map(((t,i)=>e(t,i))):e(t,0)}function ut(t,e,i){return kt(t)?K(t,e,i):t}function pt(t,e){return kt(t)?t.find(((t,i)=>e(t,i))):e(t,0)?t:void 0}function ft(t,e){const i=t.value,s=t.animation,o={delayTime:1e3*P(s.delay),enable:s.enable,value:P(t.value)*e,max:S(i)*e,min:C(i)*e,loops:0,maxLoops:P(s.count),time:0};if(s.enable){switch(o.decay=1-P(s.decay),s.mode){case"increase":o.status="increasing";break;case"decrease":o.status="decreasing";break;case"random":o.status=_()>=.5?"increasing":"decreasing"}const t="auto"===s.mode;switch(s.startValue){case"min":o.value=o.min,t&&(o.status="increasing");break;case"max":o.value=o.max,t&&(o.status="decreasing");break;default:o.value=M(o),t&&(o.status=_()>=.5?"increasing":"decreasing")}}return o.initialValue=o.value,o}function vt(t,e){if(!("percent"===t.mode)){const{mode:e,...i}=t;return i}return"x"in t?{x:t.x/100*e.width,y:t.y/100*e.height}:{width:t.width/100*e.width,height:t.height/100*e.height}}function mt(t,e){return vt(t,e)}function yt(t,e){return vt(t,e)}function gt(t){return"boolean"==typeof t}function bt(t){return"string"==typeof t}function wt(t){return"number"==typeof t}function xt(t){return"function"==typeof t}function _t(t){return"object"==typeof t&&null!==t}function kt(t){return Array.isArray(t)}class zt{constructor(){this.value=""}static create(t,e){const i=new zt;return i.load(t),void 0!==e&&(bt(e)||kt(e)?i.load({value:e}):i.load(e)),i}load(t){void 0!==t?.value&&(this.value=t.value)}}class Mt{constructor(){this.count=0,this.enable=!1,this.speed=1,this.decay=0,this.delay=0,this.sync=!1}load(t){t&&(void 0!==t.count&&(this.count=O(t.count)),void 0!==t.enable&&(this.enable=t.enable),void 0!==t.speed&&(this.speed=O(t.speed)),void 0!==t.decay&&(this.decay=O(t.decay)),void 0!==t.delay&&(this.delay=O(t.delay)),void 0!==t.sync&&(this.sync=t.sync))}}class Pt extends Mt{constructor(){super(),this.mode="auto",this.startValue="random"}load(t){super.load(t),t&&(void 0!==t.minimumValue&&(this.minimumValue=t.minimumValue),void 0!==t.mode&&(this.mode=t.mode),void 0!==t.startValue&&(this.startValue=t.startValue))}}class Ct{constructor(){this.enable=!1,this.minimumValue=0}load(t){t&&(void 0!==t.enable&&(this.enable=t.enable),void 0!==t.minimumValue&&(this.minimumValue=t.minimumValue))}}class St{constructor(){this.random=new Ct,this.value=0}load(t){t&&(gt(t.random)?this.random.enable=t.random:this.random.load(t.random),void 0!==t.value&&(this.value=O(t.value,this.random.enable?this.random.minimumValue:void 0)))}}class Ot extends St{constructor(){super(),this.animation=new Mt}get anim(){return this.animation}set anim(t){this.animation=t}load(t){if(super.load(t),!t)return;const e=t.animation??t.anim;void 0!==e&&this.animation.load(e)}}class Tt extends Ot{constructor(){super(),this.animation=new Pt}load(t){if(super.load(t),!t)return;void 0!==(t.animation??t.anim)&&(this.value=O(this.value,this.animation.enable?this.animation.minimumValue:void 0))}}class Rt{constructor(){this.radius=0,this.mass=0}load(t){t&&(void 0!==t.mass&&(this.mass=t.mass),void 0!==t.radius&&(this.radius=t.radius))}}class Dt extends St{constructor(){super(),this.density=5,this.value=50,this.limit=new Rt}load(t){t&&(super.load(t),void 0!==t.density&&(this.density=t.density),wt(t.limit)?this.limit.radius=t.limit:this.limit.load(t.limit))}}class Et{constructor(){this.color=new zt,this.color.value="#000000",this.draggable=!1,this.opacity=1,this.destroy=!0,this.orbits=!1,this.size=new Dt}load(t){void 0!==t&&(void 0!==t.color&&(this.color=zt.create(this.color,t.color)),void 0!==t.draggable&&(this.draggable=t.draggable),this.name=t.name,void 0!==t.opacity&&(this.opacity=t.opacity),void 0!==t.position&&(this.position={},void 0!==t.position.x&&(this.position.x=O(t.position.x)),void 0!==t.position.y&&(this.position.y=O(t.position.y))),void 0!==t.size&&this.size.load(t.size),void 0!==t.destroy&&(this.destroy=t.destroy),void 0!==t.orbits&&(this.orbits=t.orbits))}}const It="random",Lt="mid",At=new Map;function Ft(t){At.set(t.key,t)}function Bt(t,e,i){return i<0&&(i+=1),i>1&&(i-=1),i<1/6?t+6*(e-t)*i:i<.5?e:i<2/3?t+(e-t)*(2/3-i)*6:t}function qt(t){for(const[,e]of At)if(t.startsWith(e.stringPrefix))return e.parseString(t);const e=t.replace(/^#?([a-f\d])([a-f\d])([a-f\d])([a-f\d])?$/i,((t,e,i,s,o)=>e+e+i+i+s+s+(void 0!==o?o+o:""))),i=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})?$/i.exec(e);return i?{a:void 0!==i[4]?parseInt(i[4],16)/255:1,b:parseInt(i[3],16),g:parseInt(i[2],16),r:parseInt(i[1],16)}:void 0}function Vt(t,e,i=!0){if(!t)return;const s=bt(t)?{value:t}:t;if(bt(s.value))return Ht(s.value,e,i);if(kt(s.value))return Vt({value:K(s.value,e,i)});for(const[,t]of At){const e=t.handleRangeColor(s);if(e)return e}}function Ht(t,e,i=!0){if(!t)return;const s=bt(t)?{value:t}:t;if(bt(s.value))return s.value===It?Yt():jt(s.value);if(kt(s.value))return Ht({value:K(s.value,e,i)});for(const[,t]of At){const e=t.handleColor(s);if(e)return e}}function Ut(t,e,i=!0){const s=Ht(t,e,i);return s?$t(s):void 0}function Wt(t,e,i=!0){const s=Vt(t,e,i);return s?$t(s):void 0}function $t(t){const e=t.r/255,i=t.g/255,s=t.b/255,o=Math.max(e,i,s),n=Math.min(e,i,s),a={h:0,l:(o+n)/2,s:0};return o!==n&&(a.s=a.l<.5?(o-n)/(o+n):(o-n)/(2-o-n),a.h=e===o?(i-s)/(o-n):a.h=i===o?2+(s-e)/(o-n):4+(e-i)/(o-n)),a.l*=100,a.s*=100,a.h*=60,a.h<0&&(a.h+=360),a.h>=360&&(a.h-=360),a}function Gt(t){return qt(t)?.a}function jt(t){return qt(t)}function Nt(t){const e={b:0,g:0,r:0},i={h:t.h/360,l:t.l/100,s:t.s/100};if(i.s){const t=i.l<.5?i.l*(1+i.s):i.l+i.s-i.l*i.s,s=2*i.l-t;e.r=Bt(s,t,i.h+1/3),e.g=Bt(s,t,i.h),e.b=Bt(s,t,i.h-1/3)}else e.r=e.g=e.b=i.l;return e.r=Math.floor(255*e.r),e.g=Math.floor(255*e.g),e.b=Math.floor(255*e.b),e}function Xt(t){const e=Nt(t);return{a:t.a,b:e.b,g:e.g,r:e.r}}function Yt(t){const e=t??0;return{b:Math.floor(M(O(e,256))),g:Math.floor(M(O(e,256))),r:Math.floor(M(O(e,256)))}}function Jt(t,e){return`rgba(${t.r}, ${t.g}, ${t.b}, ${e??1})`}function Zt(t,e){return`hsla(${t.h}, ${t.s}%, ${t.l}%, ${e??1})`}function Qt(t,e,i,s){let o=t,n=e;return void 0===o.r&&(o=Nt(t)),void 0===n.r&&(n=Nt(e)),{b:z(o.b,n.b,i,s),g:z(o.g,n.g,i,s),r:z(o.r,n.r,i,s)}}function Kt(t,e,i){if(i===It)return Yt();if(i!==Lt)return i;{const i=t.getFillColor()??t.getStrokeColor(),s=e?.getFillColor()??e?.getStrokeColor();if(i&&s&&e)return Qt(i,s,t.getRadius(),e.getRadius());{const t=i??s;if(t)return Nt(t)}}}function te(t,e,i){const s=bt(t)?t:t.value;return s===It?i?Vt({value:s}):e?It:Lt:s===Lt?Lt:Vt({value:s})}function ee(t){return void 0!==t?{h:t.h.value,s:t.s.value,l:t.l.value}:void 0}function ie(t,e,i){const s={h:{enable:!1,value:t.h},s:{enable:!1,value:t.s},l:{enable:!1,value:t.l}};return e&&(se(s.h,e.h,i),se(s.s,e.s,i),se(s.l,e.l,i)),s}function se(t,e,i){t.enable=e.enable,t.enable?(t.velocity=P(e.speed)/100*i,t.decay=1-P(e.decay),t.status="increasing",t.loops=0,t.maxLoops=P(e.count),t.time=0,t.delayTime=1e3*P(e.delay),e.sync||(t.velocity*=_(),t.value*=_()),t.initialValue=t.value):t.velocity=0}class oe{constructor(t,e,i,s){this.absorbers=t,this.container=e,this._calcPosition=()=>{const t=B({size:this.container.canvas.size,position:this.options.position});return m.create(t.x,t.y)},this._updateParticlePosition=(t,e)=>{if(t.destroyed)return;const i=this.container,s=i.canvas.size;if(t.needsNewPosition){const e=F({size:s});t.position.setTo(e),t.velocity.setTo(t.initialVelocity),t.absorberOrbit=void 0,t.needsNewPosition=!1}if(this.options.orbits){if(void 0===t.absorberOrbit&&(t.absorberOrbit=m.create(0,0),t.absorberOrbit.length=D(t.getPosition(),this.position),t.absorberOrbit.angle=_()*Math.PI*2),t.absorberOrbit.length<=this.size&&!this.options.destroy){const e=Math.min(s.width,s.height);t.absorberOrbit.length=e*(.2*_()-.1+1)}void 0===t.absorberOrbitDirection&&(t.absorberOrbitDirection=t.velocity.x>=0?"clockwise":"counter-clockwise");const o=t.absorberOrbit.length,n=t.absorberOrbit.angle,a=t.absorberOrbitDirection;t.velocity.setTo(m.origin);const r={x:"clockwise"===a?Math.cos:Math.sin,y:"clockwise"===a?Math.sin:Math.cos};t.position.x=this.position.x+o*r.x(n),t.position.y=this.position.y+o*r.y(n),t.absorberOrbit.length-=e.length,t.absorberOrbit.angle+=(t.retina.moveSpeed??0)*i.retina.pixelRatio/100*i.retina.reduceFactor}else{const i=m.origin;i.length=e.length,i.angle=e.angle,t.velocity.addTo(i)}},this.initialPosition=s?m.create(s.x,s.y):void 0,i instanceof Et?this.options=i:(this.options=new Et,this.options.load(i)),this.dragging=!1,this.name=this.options.name,this.opacity=this.options.opacity,this.size=P(this.options.size.value)*e.retina.pixelRatio,this.mass=this.size*this.options.size.density*e.retina.reduceFactor;const o=this.options.size.limit;this.limit={radius:o.radius*e.retina.pixelRatio*e.retina.reduceFactor,mass:o.mass},this.color=Vt(this.options.color)??{b:0,g:0,r:0},this.position=this.initialPosition?.copy()??this._calcPosition()}attract(t){const e=this.container,i=this.options;if(i.draggable){const t=e.interactivity.mouse;if(t.clicking&&t.downPosition){D(this.position,t.downPosition)<=this.size&&(this.dragging=!0)}else this.dragging=!1;this.dragging&&t.position&&(this.position.x=t.position.x,this.position.y=t.position.y)}const s=t.getPosition(),{dx:o,dy:n,distance:a}=R(this.position,s),r=m.create(o,n);if(r.length=this.mass/Math.pow(a,2)*e.retina.reduceFactor,at.getRadius()&&avoid 0===t||wt(t)?this.array[t||0]:this.array.find((e=>e.name===t)),t.addAbsorber=(t,e)=>this.addAbsorber(t,e)}addAbsorber(t,e){const i=new oe(this,this.container,t,e);return this.array.push(i),i}draw(t){for(const e of this.array)e.draw(t)}handleClickMode(t){const e=this.absorbers,i=this.interactivityAbsorbers;if("absorber"===t){const t=ut(i)??ut(e),s=this.container.interactivity.mouse.clickPosition;this.addAbsorber(t,s)}}async init(){this.absorbers=this.container.actualOptions.absorbers,this.interactivityAbsorbers=this.container.actualOptions.interactivity.modes.absorbers,dt(this.absorbers,(t=>{this.addAbsorber(t)}))}particleUpdate(t){for(const e of this.array)if(e.attract(t),t.destroyed)break}removeAbsorber(t){const e=this.array.indexOf(t);e>=0&&this.array.splice(e,1)}resize(){for(const t of this.array)t.resize()}stop(){this.array=[]}}class ae{constructor(){this.id="absorbers"}getPlugin(t){return new ne(t)}loadOptions(t,e){(this.needsPlugin(t)||this.needsPlugin(e))&&(e?.absorbers&&(t.absorbers=dt(e.absorbers,(t=>{const e=new Et;return e.load(t),e}))),t.interactivity.modes.absorbers=dt(e?.interactivity?.modes?.absorbers,(t=>{const e=new Et;return e.load(t),e})))}needsPlugin(t){if(!t)return!1;const e=t.absorbers;return kt(e)?!!e.length:!!e||!(!t.interactivity?.events?.onClick?.mode||!J("absorber",t.interactivity.events.onClick.mode))}}class re{load(t){t&&(void 0!==t.bottom&&(this.bottom=O(t.bottom)),void 0!==t.left&&(this.left=O(t.left)),void 0!==t.right&&(this.right=O(t.right)),void 0!==t.top&&(this.top=O(t.top)))}}class ce extends St{constructor(){super(),this.value=3}}class le extends St{constructor(){super(),this.value={min:4,max:9}}}class he{constructor(){this.count=1,this.factor=new ce,this.rate=new le,this.sizeOffset=!0}load(t){t&&(void 0!==t.color&&(this.color=zt.create(this.color,t.color)),void 0!==t.count&&(this.count=t.count),this.factor.load(t.factor),this.rate.load(t.rate),this.particles=dt(t.particles,(t=>st({},t))),void 0!==t.sizeOffset&&(this.sizeOffset=t.sizeOffset),t.colorOffset&&(this.colorOffset=this.colorOffset??{},void 0!==t.colorOffset.h&&(this.colorOffset.h=t.colorOffset.h),void 0!==t.colorOffset.s&&(this.colorOffset.s=t.colorOffset.s),void 0!==t.colorOffset.l&&(this.colorOffset.l=t.colorOffset.l)))}}class de{constructor(){this.bounds=new re,this.mode="none",this.split=new he}load(t){t&&(t.mode&&(this.mode=t.mode),t.bounds&&this.bounds.load(t.bounds),this.split.load(t.split))}}class ue{constructor(){this.count=0,this.enable=!1,this.offset=0,this.speed=1,this.delay=0,this.decay=0,this.sync=!0}load(t){t&&(void 0!==t.count&&(this.count=O(t.count)),void 0!==t.enable&&(this.enable=t.enable),void 0!==t.offset&&(this.offset=O(t.offset)),void 0!==t.speed&&(this.speed=O(t.speed)),void 0!==t.decay&&(this.decay=O(t.decay)),void 0!==t.delay&&(this.delay=O(t.delay)),void 0!==t.sync&&(this.sync=t.sync))}}class pe{constructor(){this.h=new ue,this.s=new ue,this.l=new ue}load(t){t&&(this.h.load(t.h),this.s.load(t.s),this.l.load(t.l))}}class fe extends zt{constructor(){super(),this.animation=new pe}static create(t,e){const i=new fe;return i.load(t),void 0!==e&&(bt(e)||kt(e)?i.load({value:e}):i.load(e)),i}load(t){if(super.load(t),!t)return;const e=t.animation;void 0!==e&&(void 0!==e.enable?this.animation.h.load(e):this.animation.load(t.animation))}}class ve{constructor(){this.speed=2}load(t){t&&void 0!==t.speed&&(this.speed=t.speed)}}class me{constructor(){this.enable=!0,this.retries=0}load(t){t&&(void 0!==t.enable&&(this.enable=t.enable),void 0!==t.retries&&(this.retries=t.retries))}}class ye extends St{constructor(){super(),this.random.minimumValue=.1,this.value=1}}class ge{constructor(){this.horizontal=new ye,this.vertical=new ye}load(t){t&&(this.horizontal.load(t.horizontal),this.vertical.load(t.vertical))}}class be{constructor(){this.absorb=new ve,this.bounce=new ge,this.enable=!1,this.maxSpeed=50,this.mode="bounce",this.overlap=new me}load(t){t&&(this.absorb.load(t.absorb),this.bounce.load(t.bounce),void 0!==t.enable&&(this.enable=t.enable),void 0!==t.maxSpeed&&(this.maxSpeed=O(t.maxSpeed)),void 0!==t.mode&&(this.mode=t.mode),this.overlap.load(t.overlap))}}class we{constructor(){this.offset=0,this.value=90}load(t){t&&(void 0!==t.offset&&(this.offset=O(t.offset)),void 0!==t.value&&(this.value=O(t.value)))}}class xe{constructor(){this.distance=200,this.enable=!1,this.rotate={x:3e3,y:3e3}}get rotateX(){return this.rotate.x}set rotateX(t){this.rotate.x=t}get rotateY(){return this.rotate.y}set rotateY(t){this.rotate.y=t}load(t){if(!t)return;void 0!==t.distance&&(this.distance=O(t.distance)),void 0!==t.enable&&(this.enable=t.enable);const e=t.rotate?.x??t.rotateX;void 0!==e&&(this.rotate.x=e);const i=t.rotate?.y??t.rotateY;void 0!==i&&(this.rotate.y=i)}}class _e{constructor(){this.x=50,this.y=50,this.mode="percent",this.radius=0}load(t){t&&(void 0!==t.x&&(this.x=t.x),void 0!==t.y&&(this.y=t.y),void 0!==t.mode&&(this.mode=t.mode),void 0!==t.radius&&(this.radius=t.radius))}}class ke{constructor(){this.acceleration=9.81,this.enable=!1,this.inverse=!1,this.maxSpeed=50}load(t){t&&(void 0!==t.acceleration&&(this.acceleration=O(t.acceleration)),void 0!==t.enable&&(this.enable=t.enable),void 0!==t.inverse&&(this.inverse=t.inverse),void 0!==t.maxSpeed&&(this.maxSpeed=O(t.maxSpeed)))}}class ze{constructor(){this.clamp=!0,this.delay=new St,this.enable=!1,this.options={}}load(t){t&&(void 0!==t.clamp&&(this.clamp=t.clamp),this.delay.load(t.delay),void 0!==t.enable&&(this.enable=t.enable),this.generator=t.generator,t.options&&(this.options=st(this.options,t.options)))}}class Me{load(t){t&&(void 0!==t.color&&(this.color=zt.create(this.color,t.color)),void 0!==t.image&&(this.image=t.image))}}class Pe{constructor(){this.enable=!1,this.length=10,this.fill=new Me}get fillColor(){return this.fill.color}set fillColor(t){this.fill.load({color:t})}load(t){t&&(void 0!==t.enable&&(this.enable=t.enable),void 0===t.fill&&void 0===t.fillColor||this.fill.load(t.fill||{color:t.fillColor}),void 0!==t.length&&(this.length=t.length))}}class Ce{constructor(){this.default="out"}load(t){t&&(void 0!==t.default&&(this.default=t.default),this.bottom=t.bottom??t.default,this.left=t.left??t.default,this.right=t.right??t.default,this.top=t.top??t.default)}}class Se{constructor(){this.acceleration=0,this.enable=!1}load(t){t&&(void 0!==t.acceleration&&(this.acceleration=O(t.acceleration)),void 0!==t.enable&&(this.enable=t.enable),t.position&&(this.position=st({},t.position)))}}class Oe{constructor(){this.angle=new we,this.attract=new xe,this.center=new _e,this.decay=0,this.distance={},this.direction="none",this.drift=0,this.enable=!1,this.gravity=new ke,this.path=new ze,this.outModes=new Ce,this.random=!1,this.size=!1,this.speed=2,this.spin=new Se,this.straight=!1,this.trail=new Pe,this.vibrate=!1,this.warp=!1}get bounce(){return this.collisions}set bounce(t){this.collisions=t}get collisions(){return!1}set collisions(t){}get noise(){return this.path}set noise(t){this.path=t}get outMode(){return this.outModes.default}set outMode(t){this.outModes.default=t}get out_mode(){return this.outMode}set out_mode(t){this.outMode=t}load(t){if(!t)return;this.angle.load(wt(t.angle)?{value:t.angle}:t.angle),this.attract.load(t.attract),this.center.load(t.center),void 0!==t.decay&&(this.decay=O(t.decay)),void 0!==t.direction&&(this.direction=t.direction),void 0!==t.distance&&(this.distance=wt(t.distance)?{horizontal:t.distance,vertical:t.distance}:{...t.distance}),void 0!==t.drift&&(this.drift=O(t.drift)),void 0!==t.enable&&(this.enable=t.enable),this.gravity.load(t.gravity);const e=t.outModes??t.outMode??t.out_mode;void 0!==e&&(_t(e)?this.outModes.load(e):this.outModes.load({default:e})),this.path.load(t.path??t.noise),void 0!==t.random&&(this.random=t.random),void 0!==t.size&&(this.size=t.size),void 0!==t.speed&&(this.speed=O(t.speed)),this.spin.load(t.spin),void 0!==t.straight&&(this.straight=t.straight),this.trail.load(t.trail),void 0!==t.vibrate&&(this.vibrate=t.vibrate),void 0!==t.warp&&(this.warp=t.warp)}}class Te extends Pt{constructor(){super(),this.destroy="none",this.speed=2}get opacity_min(){return this.minimumValue}set opacity_min(t){this.minimumValue=t}load(t){void 0!==t?.opacity_min&&void 0===t.minimumValue&&(t.minimumValue=t.opacity_min),super.load(t),t&&void 0!==t.destroy&&(this.destroy=t.destroy)}}class Re extends St{constructor(){super(),this.animation=new Te,this.random.minimumValue=.1,this.value=1}get anim(){return this.animation}set anim(t){this.animation=t}load(t){if(!t)return;super.load(t);const e=t.animation??t.anim;void 0!==e&&(this.animation.load(e),this.value=O(this.value,this.animation.enable?this.animation.minimumValue:void 0))}}class De{constructor(){this.enable=!1,this.width=1920,this.height=1080}get area(){return this.width}set area(t){this.width=t}get factor(){return this.height}set factor(t){this.height=t}get value_area(){return this.area}set value_area(t){this.area=t}load(t){if(!t)return;void 0!==t.enable&&(this.enable=t.enable);const e=t.width??t.area??t.value_area;void 0!==e&&(this.width=e);const i=t.height??t.factor;void 0!==i&&(this.height=i)}}class Ee{constructor(){this.density=new De,this.limit=0,this.value=0}get max(){return this.limit}set max(t){this.limit=t}load(t){if(!t)return;this.density.load(t.density);const e=t.limit??t.max;void 0!==e&&(this.limit=e),void 0!==t.value&&(this.value=t.value)}}class Ie{constructor(){this.blur=0,this.color=new zt,this.enable=!1,this.offset={x:0,y:0},this.color.value="#000"}load(t){t&&(void 0!==t.blur&&(this.blur=t.blur),this.color=zt.create(this.color,t.color),void 0!==t.enable&&(this.enable=t.enable),void 0!==t.offset&&(void 0!==t.offset.x&&(this.offset.x=t.offset.x),void 0!==t.offset.y&&(this.offset.y=t.offset.y)))}}const Le="character",Ae="char",Fe="image",Be="images",qe="polygon",Ve="star";class He{constructor(){this.loadShape=(t,e,i,s)=>{if(!t)return;const o=kt(t),n=o?[]:{},a=o!==kt(this.options[e]),r=o!==kt(this.options[i]);a&&(this.options[e]=n),r&&s&&(this.options[i]=n),this.options[e]=st(this.options[e]??n,t),this.options[i]&&!s||(this.options[i]=st(this.options[i]??n,t))},this.close=!0,this.fill=!0,this.options={},this.type="circle"}get character(){return this.options[Le]??this.options[Ae]}set character(t){this.options[Ae]=this.options[Le]=t}get custom(){return this.options}set custom(t){this.options=t}get image(){return this.options[Fe]??this.options[Be]}set image(t){this.options[Be]=this.options[Fe]=t}get images(){return this.image}set images(t){this.image=t}get polygon(){return this.options[qe]??this.options[Ve]}set polygon(t){this.options[Ve]=this.options[qe]=t}get stroke(){return[]}set stroke(t){}load(t){if(!t)return;const e=t.options??t.custom;if(void 0!==e)for(const t in e){const i=e[t];i&&(this.options[t]=st(this.options[t]??{},i))}this.loadShape(t.character,Le,Ae,!0),this.loadShape(t.polygon,qe,Ve,!1),this.loadShape(t.image??t.images,Fe,Be,!0),void 0!==t.close&&(this.close=t.close),void 0!==t.fill&&(this.fill=t.fill),void 0!==t.type&&(this.type=t.type)}}class Ue extends Pt{constructor(){super(),this.destroy="none",this.speed=5}get size_min(){return this.minimumValue}set size_min(t){this.minimumValue=t}load(t){void 0!==t?.size_min&&void 0===t.minimumValue&&(t.minimumValue=t.size_min),super.load(t),t&&void 0!==t.destroy&&(this.destroy=t.destroy)}}class We extends St{constructor(){super(),this.animation=new Ue,this.random.minimumValue=1,this.value=3}get anim(){return this.animation}set anim(t){this.animation=t}load(t){if(super.load(t),!t)return;const e=t.animation??t.anim;void 0!==e&&(this.animation.load(e),this.value=O(this.value,this.animation.enable?this.animation.minimumValue:void 0))}}class $e{constructor(){this.width=0}load(t){t&&(void 0!==t.color&&(this.color=fe.create(this.color,t.color)),void 0!==t.width&&(this.width=O(t.width)),void 0!==t.opacity&&(this.opacity=O(t.opacity)))}}class Ge extends St{constructor(){super(),this.opacityRate=1,this.sizeRate=1,this.velocityRate=1}load(t){super.load(t),t&&(void 0!==t.opacityRate&&(this.opacityRate=t.opacityRate),void 0!==t.sizeRate&&(this.sizeRate=t.sizeRate),void 0!==t.velocityRate&&(this.velocityRate=t.velocityRate))}}class je{constructor(t,e){this._engine=t,this._container=e,this.bounce=new ge,this.collisions=new be,this.color=new fe,this.color.value="#fff",this.groups={},this.move=new Oe,this.number=new Ee,this.opacity=new Re,this.reduceDuplicates=!1,this.shadow=new Ie,this.shape=new He,this.size=new We,this.stroke=new $e,this.zIndex=new Ge}load(t){if(!t)return;if(this.bounce.load(t.bounce),this.color.load(fe.create(this.color,t.color)),void 0!==t.groups)for(const e in t.groups){const i=t.groups[e];void 0!==i&&(this.groups[e]=st(this.groups[e]??{},i))}this.move.load(t.move),this.number.load(t.number),this.opacity.load(t.opacity),void 0!==t.reduceDuplicates&&(this.reduceDuplicates=t.reduceDuplicates),this.shape.load(t.shape),this.size.load(t.size),this.shadow.load(t.shadow),this.zIndex.load(t.zIndex);const e=t.move?.collisions??t.move?.bounce;void 0!==e&&(this.collisions.enable=e),this.collisions.load(t.collisions),void 0!==t.interactivity&&(this.interactivity=st({},t.interactivity));const i=t.stroke??t.shape?.stroke;if(i&&(this.stroke=dt(i,(t=>{const e=new $e;return e.load(t),e}))),this._container){const e=this._engine.plugins.updaters.get(this._container);if(e)for(const i of e)i.loadOptions&&i.loadOptions(this,t);const i=this._engine.plugins.interactors.get(this._container);if(i)for(const e of i)e.loadParticlesOptions&&e.loadParticlesOptions(this,t)}}}function Ne(t,...e){for(const i of e)t.load(i)}function Xe(t,e,...i){const s=new je(t,e);return Ne(s,...i),s}function Ye(t,e,i,s){const o=i.options.destroy;if(!o)return;const n=o.split,a=Xe(t,e,i.options),r=T(n.factor),c=i.getFillColor();n.color?a.color.load(n.color):n.colorOffset&&c?a.color.load({value:{hsl:{h:c.h+P(n.colorOffset.h??0),s:c.s+P(n.colorOffset.s??0),l:c.l+P(n.colorOffset.l??0)}}}):a.color.load({value:{hsl:i.getFillColor()}}),a.move.load({center:{x:i.position.x,y:i.position.y,mode:"precise"}}),wt(a.size.value)?a.size.value/=r:(a.size.value.min/=r,a.size.value.max/=r),a.load(s);const l=n.sizeOffset?O(-i.size.value,i.size.value):0,h={x:i.position.x+M(l),y:i.position.y+M(l)};return e.particles.addParticle(h,a,i.group,(t=>!(t.size.value<.5)&&(t.velocity.length=M(O(i.velocity.length,t.velocity.length)),t.splitCount=(i.splitCount??0)+1,t.unbreakable=!0,setTimeout((()=>{t.unbreakable=!1}),500),!0)))}class Je{constructor(t,e){this.engine=t,this.container=e}init(t){const e=this.container,i=t.options.destroy;if(!i)return;t.splitCount=0;const s=i.bounds;t.destroyBounds||(t.destroyBounds={});const{bottom:o,left:n,right:a,top:r}=s,{destroyBounds:c}=t,l=e.canvas.size;o&&(c.bottom=P(o)*l.height/100),n&&(c.left=P(n)*l.width/100),a&&(c.right=P(a)*l.width/100),r&&(c.top=P(r)*l.height/100)}isEnabled(t){return!t.destroyed}loadOptions(t,...e){t.destroy||(t.destroy=new de);for(const i of e)t.destroy.load(i?.destroy)}particleDestroyed(t,e){if(e)return;const i=t.options.destroy;i&&"split"===i.mode&&function(t,e,i){const s=i.options.destroy;if(!s)return;const o=s.split;if(o.count>=0&&(void 0===i.splitCount||i.splitCount++>o.count))return;const n=T(o.rate),a=ut(o.particles);for(let s=0;s=i.bottom||void 0!==i.left&&e.x<=i.left||void 0!==i.right&&e.x>=i.right||void 0!==i.top&&e.y<=i.top)&&t.destroy()}}class Ze{randomPosition(t,e,i){const[s,o]=[e.width/2,e.height/2],n=((t,e)=>{const i=_()/4,s=Math.atan(e/t*Math.tan(2*Math.PI*i)),o=_();return o<.25?s:o<.5?Math.PI-s:o<.75?Math.PI+s:-s})(s,o),a=(h=n,(c=s)*(l=o)/Math.sqrt((l*Math.cos(h))**2+(c*Math.sin(h))**2)),r=i?a*Math.sqrt(_()):a;var c,l,h;return{x:t.x+r*Math.cos(n),y:t.y+r*Math.sin(n)}}}class Qe{constructor(){this.wait=!1}load(t){t&&(void 0!==t.count&&(this.count=t.count),void 0!==t.delay&&(this.delay=O(t.delay)),void 0!==t.duration&&(this.duration=O(t.duration)),void 0!==t.wait&&(this.wait=t.wait))}}class Ke{constructor(){this.quantity=1,this.delay=.1}load(t){void 0!==t&&(void 0!==t.quantity&&(this.quantity=O(t.quantity)),void 0!==t.delay&&(this.delay=O(t.delay)))}}class ti{constructor(){this.mode="percent",this.height=0,this.width=0}load(t){void 0!==t&&(void 0!==t.mode&&(this.mode=t.mode),void 0!==t.height&&(this.height=t.height),void 0!==t.width&&(this.width=t.width))}}class ei{constructor(){this.autoPlay=!0,this.fill=!0,this.life=new Qe,this.rate=new Ke,this.shape="square",this.startCount=0}load(t){t&&(void 0!==t.autoPlay&&(this.autoPlay=t.autoPlay),void 0!==t.size&&(this.size||(this.size=new ti),this.size.load(t.size)),void 0!==t.direction&&(this.direction=t.direction),this.domId=t.domId,void 0!==t.fill&&(this.fill=t.fill),this.life.load(t.life),this.name=t.name,this.particles=dt(t.particles,(t=>st({},t))),this.rate.load(t.rate),void 0!==t.shape&&(this.shape=t.shape),void 0!==t.position&&(this.position={},void 0!==t.position.x&&(this.position.x=O(t.position.x)),void 0!==t.position.y&&(this.position.y=O(t.position.y))),void 0!==t.spawnColor&&(void 0===this.spawnColor&&(this.spawnColor=new fe),this.spawnColor.load(t.spawnColor)),void 0!==t.startCount&&(this.startCount=t.startCount))}}class ii{constructor(t,e,i,s,o){this.emitters=e,this.container=i,this._calcPosition=()=>B({size:this.container.canvas.size,position:this.options.position}),this._destroy=()=>{this.emitters.removeEmitter(this),this._engine.dispatchEvent("emitterDestroyed",{container:this.container,data:{emitter:this}})},this._emit=()=>{if(this._paused)return;const t=P(this.options.rate.quantity);this._emitParticles(t)},this._emitParticles=t=>{const e=this.getPosition(),i=this.getSize(),s=ut(this._particlesOptions);for(let o=0;o{if(this._paused)return;const t=void 0!==this.options.life?.duration?P(this.options.life.duration):void 0;this.container.retina.reduceFactor&&(this._lifeCount>0||this._immortal)&&void 0!==t&&t>0&&(this._duration=1e3*t)},this._setColorAnimation=(t,e,i)=>{const s=this.container;if(!t.enable)return e;const o=M(t.offset),n=1e3*P(this.options.rate.delay)/s.retina.reduceFactor;return(e+P(t.speed??0)*s.fpsLimit/n+3.6*o)%i},this._engine=t,this._currentDuration=0,this._currentEmitDelay=0,this._currentSpawnDelay=0,this._initialPosition=o,s instanceof ei?this.options=s:(this.options=new ei,this.options.load(s)),this._spawnDelay=1e3*P(this.options.life.delay??0)/this.container.retina.reduceFactor,this.position=this._initialPosition??this._calcPosition(),this.name=this.options.name,this._shape=this._engine.emitterShapeManager?.getShape(this.options.shape),this.fill=this.options.fill,this._firstSpawn=!this.options.life.wait,this._startParticlesAdded=!1;let n=st({},this.options.particles);n??={},n.move??={},n.move.direction??=this.options.direction,this.options.spawnColor&&(this.spawnColor=Wt(this.options.spawnColor)),this._paused=!this.options.autoPlay,this._particlesOptions=n,this.size=this.options.size??(()=>{const t=new ti;return t.load({height:0,mode:"percent",width:0}),t})(),this._lifeCount=this.options.life.count??-1,this._immortal=this._lifeCount<=0,this._engine.dispatchEvent("emitterCreated",{container:i,data:{emitter:this}}),this.play()}externalPause(){this._paused=!0,this.pause()}externalPlay(){this._paused=!1,this.play()}getPosition(){if(this.options.domId){const t=this.container,e=document.getElementById(this.options.domId);if(e){const i=e.getBoundingClientRect();return{x:(i.x+i.width/2)*t.retina.pixelRatio,y:(i.y+i.height/2)*t.retina.pixelRatio}}}return this.position}getSize(){const t=this.container;if(this.options.domId){const e=document.getElementById(this.options.domId);if(e){const i=e.getBoundingClientRect();return{width:i.width*t.retina.pixelRatio,height:i.height*t.retina.pixelRatio}}}return yt(this.size,t.canvas.size)}pause(){this._paused||delete this._emitDelay}play(){if(!this._paused&&this.container.retina.reduceFactor&&(this._lifeCount>0||this._immortal||!this.options.life.count)&&(this._firstSpawn||this._currentSpawnDelay>=(this._spawnDelay??0))){if(void 0===this._emitDelay){const t=P(this.options.rate.delay);this._emitDelay=1e3*t/this.container.retina.reduceFactor}(this._lifeCount>0||this._immortal)&&this._prepareToDie()}}resize(){const t=this._initialPosition;this.position=t&&tt(t,this.container.canvas.size,m.origin)?t:this._calcPosition()}update(t){this._paused||(this._firstSpawn&&(this._firstSpawn=!1,this._currentSpawnDelay=this._spawnDelay??0,this._currentEmitDelay=this._emitDelay??0),this._startParticlesAdded||(this._startParticlesAdded=!0,this._emitParticles(this.options.startCount)),void 0!==this._duration&&(this._currentDuration+=t.value,this._currentDuration>=this._duration&&(this.pause(),void 0!==this._spawnDelay&&delete this._spawnDelay,this._immortal||this._lifeCount--,this._lifeCount>0||this._immortal?(this.position=this._calcPosition(),this._spawnDelay=1e3*P(this.options.life.delay??0)/this.container.retina.reduceFactor):this._destroy(),this._currentDuration-=this._duration,delete this._duration)),void 0!==this._spawnDelay&&(this._currentSpawnDelay+=t.value,this._currentSpawnDelay>=this._spawnDelay&&(this._engine.dispatchEvent("emitterPlay",{container:this.container}),this.play(),this._currentSpawnDelay-=this._currentSpawnDelay,delete this._spawnDelay)),void 0!==this._emitDelay&&(this._currentEmitDelay+=t.value,this._currentEmitDelay>=this._emitDelay&&(this._emit(),this._currentEmitDelay-=this._emitDelay)))}}class si{constructor(t,e){this.container=e,this._engine=t,this.array=[],this.emitters=[],this.interactivityEmitters={random:{count:1,enable:!1},value:[]},e.getEmitter=t=>void 0===t||wt(t)?this.array[t||0]:this.array.find((e=>e.name===t)),e.addEmitter=(t,e)=>this.addEmitter(t,e),e.removeEmitter=t=>{const i=e.getEmitter(t);i&&this.removeEmitter(i)},e.playEmitter=t=>{const i=e.getEmitter(t);i&&i.externalPlay()},e.pauseEmitter=t=>{const i=e.getEmitter(t);i&&i.externalPause()}}addEmitter(t,e){const i=new ei;i.load(t);const s=new ii(this._engine,this,this.container,i,e);return this.array.push(s),s}handleClickMode(t){const e=this.emitters,i=this.interactivityEmitters;if("emitter"!==t)return;let s;if(i&&kt(i.value))if(i.value.length>0&&i.random.enable){s=[];const t=[];for(let e=0;e{this.addEmitter(t,n)}))}async init(){if(this.emitters=this.container.actualOptions.emitters,this.interactivityEmitters=this.container.actualOptions.interactivity.modes.emitters,this.emitters)if(kt(this.emitters))for(const t of this.emitters)this.addEmitter(t);else this.addEmitter(this.emitters)}pause(){for(const t of this.array)t.pause()}play(){for(const t of this.array)t.play()}removeEmitter(t){const e=this.array.indexOf(t);e>=0&&this.array.splice(e,1)}resize(){for(const t of this.array)t.resize()}stop(){this.array=[]}update(t){for(const e of this.array)e.update(t)}}const oi=new Map;class ni{constructor(t){this._engine=t}addShape(t,e){this.getShape(t)||oi.set(t,e)}getShape(t){return oi.get(t)}getSupportedShapes(){return oi.keys()}}function ai(t,e){return t+e*(_()-.5)}class ri{randomPosition(t,e,i){if(i)return{x:ai(t.x,e.width),y:ai(t.y,e.height)};{const i=e.width/2,s=e.height/2,o=Math.floor(4*_()),n=2*(_()-.5);switch(o){case 0:return{x:t.x+n*i,y:t.y-s};case 1:return{x:t.x-i,y:t.y+n*s};case 2:return{x:t.x+n*i,y:t.y+s};default:return{x:t.x+i,y:t.y+n*s}}}}}class ci{constructor(t){this._engine=t,this.id="emitters"}getPlugin(t){return new si(this._engine,t)}loadOptions(t,e){if(!this.needsPlugin(t)&&!this.needsPlugin(e))return;e?.emitters&&(t.emitters=dt(e.emitters,(t=>{const e=new ei;return e.load(t),e})));const i=e?.interactivity?.modes?.emitters;if(i)if(kt(i))t.interactivity.modes.emitters={random:{count:1,enable:!0},value:i.map((t=>{const e=new ei;return e.load(t),e}))};else{const e=i;if(void 0!==e.value)if(kt(e.value))t.interactivity.modes.emitters={random:{count:e.random.count??1,enable:e.random.enable??!1},value:e.value.map((t=>{const e=new ei;return e.load(t),e}))};else{const i=new ei;i.load(e.value),t.interactivity.modes.emitters={random:{count:e.random.count??1,enable:e.random.enable??!1},value:i}}else{(t.interactivity.modes.emitters={random:{count:1,enable:!1},value:new ei}).value.load(i)}}}needsPlugin(t){if(!t)return!1;const e=t.emitters;return kt(e)&&!!e.length||void 0!==e||!!t.interactivity?.events?.onClick?.mode&&J("emitter",t.interactivity.events.onClick.mode)}}class li{constructor(t){this.container=t,this.type="external"}}class hi{constructor(){this.delay=1,this.pauseOnStop=!1,this.quantity=1}load(t){t&&(void 0!==t.delay&&(this.delay=t.delay),void 0!==t.quantity&&(this.quantity=t.quantity),void 0!==t.particles&&(this.particles=st({},t.particles)),void 0!==t.pauseOnStop&&(this.pauseOnStop=t.pauseOnStop))}}class di extends li{constructor(t){super(t),this._delay=0}clear(){}init(){}async interact(t){const e=this.container,{interactivity:i}=e;if(!e.retina.reduceFactor)return;const s=e.actualOptions.interactivity.modes.trail;if(!s)return;const o=1e3*s.delay/this.container.retina.reduceFactor;if(this._delay=.5?"darken":"enlighten";t.roll.alter={type:i,value:P("darken"===i?e.darken.value:e.enlighten.value)}}else e.darken.enable?t.roll.alter={type:"darken",value:P(e.darken.value)}:e.enlighten.enable&&(t.roll.alter={type:"enlighten",value:P(e.enlighten.value)});else t.roll={enable:!1,horizontal:!1,vertical:!1,angle:0,speed:0}}(t)}isEnabled(t){const e=t.options.roll;return!t.destroyed&&!t.spawning&&!!e?.enable}loadOptions(t,...e){t.roll||(t.roll=new pi);for(const i of e)t.roll.load(i?.roll)}update(t,e){this.isEnabled(t)&&function(t,e){const i=t.options.roll,s=t.roll;if(!s||!i?.enable)return;const o=s.speed*e.factor,n=2*Math.PI;s.angle+=o,s.angle>n&&(s.angle-=n)}(t,e)}}function vi(t,e,i){t.beginPath(),t.moveTo(e.x,e.y),t.lineTo(i.x,i.y),t.closePath()}function mi(t,e,i,s){t.beginPath(),t.moveTo(e.x,e.y),t.lineTo(i.x,i.y),t.lineTo(s.x,s.y),t.closePath()}function yi(t,e,i){t.fillStyle=i??"rgba(0,0,0,0)",t.fillRect(0,0,e.width,e.height)}function gi(t,e,i,s){i&&(t.globalAlpha=s,t.drawImage(i,0,0,e.width,e.height),t.globalAlpha=1)}function bi(t,e){t.clearRect(0,0,e.width,e.height)}function wi(t){const{container:e,context:i,particle:s,delta:o,colorStyles:n,backgroundMask:a,composite:r,radius:c,opacity:l,shadow:h,transform:d}=t,u=s.getPosition(),p=s.rotation+(s.pathRotation?s.velocity.angle:0),f=Math.sin(p),v=Math.cos(p),m={a:v*(d.a??1),b:f*(d.b??1),c:-f*(d.c??1),d:v*(d.d??1)};i.setTransform(m.a,m.b,m.c,m.d,u.x,u.y),i.beginPath(),a&&(i.globalCompositeOperation=r);const y=s.shadowColor;h.enable&&y&&(i.shadowBlur=h.blur,i.shadowColor=Jt(y),i.shadowOffsetX=h.offset.x,i.shadowOffsetY=h.offset.y),n.fill&&(i.fillStyle=n.fill);const g=s.strokeWidth??0;i.lineWidth=g,n.stroke&&(i.strokeStyle=n.stroke),xi(e,i,s,c,l,o),g>0&&i.stroke(),s.close&&i.closePath(),s.fill&&i.fill(),_i(e,i,s,c,l,o),i.globalCompositeOperation="source-over",i.setTransform(1,0,0,1,0,0)}function xi(t,e,i,s,o,n){if(!i.shape)return;const a=t.drawers.get(i.shape);a&&a.draw(e,i,s,o,n,t.retina.pixelRatio)}function _i(t,e,i,s,o,n){if(!i.shape)return;const a=t.drawers.get(i.shape);a&&a.afterEffect&&a.afterEffect(e,i,s,o,n,t.retina.pixelRatio)}function ki(t,e,i){e.draw&&e.draw(t,i)}function zi(t,e,i,s){e.drawParticle&&e.drawParticle(t,i,s)}function Mi(t,e,i){return{h:t.h,s:t.s,l:t.l+("darken"===e?-1:1)*i}}function Pi(t,e,i){const s=e[i];void 0!==s&&(t[i]=(t[i]??1)*s)}class Ci{constructor(t){this.container=t,this._applyPostDrawUpdaters=t=>{for(const e of this._postDrawUpdaters)e.afterDraw&&e.afterDraw(t)},this._applyPreDrawUpdaters=(t,e,i,s,o,n)=>{for(const a of this._preDrawUpdaters){if(a.getColorStyles){const{fill:n,stroke:r}=a.getColorStyles(e,t,i,s);n&&(o.fill=n),r&&(o.stroke=r)}if(a.getTransformValues){const t=a.getTransformValues(e);for(const e in t)Pi(n,t,e)}a.beforeDraw&&a.beforeDraw(e)}},this._applyResizePlugins=()=>{for(const t of this._resizePlugins)t.resize&&t.resize()},this._getPluginParticleColors=t=>{let e,i;for(const s of this._colorPlugins)if(!e&&s.particleFillColor&&(e=Wt(s.particleFillColor(t))),!i&&s.particleStrokeColor&&(i=Wt(s.particleStrokeColor(t))),e&&i)break;return[e,i]},this._initCover=()=>{const t=this.container.actualOptions.backgroundMask.cover,e=Vt(t.color);if(e){const i={...e,a:t.opacity};this._coverColorStyle=Jt(i,i.a)}},this._initStyle=()=>{const t=this.element,e=this.container.actualOptions;if(t){this._fullScreen?(this._originalStyle=st({},t.style),this._setFullScreenStyle()):this._resetOriginalStyle();for(const i in e.style){if(!i||!e.style)continue;const s=e.style[i];s&&t.style.setProperty(i,s,"important")}}},this._initTrail=async()=>{const t=this.container.actualOptions,e=t.particles.move.trail,i=e.fill;if(e.enable)if(i.color){const e=Vt(i.color);if(!e)return;const s=t.particles.move.trail;this._trailFill={color:{...e},opacity:1/s.length}}else await new Promise(((t,s)=>{if(!i.image)return;const o=document.createElement("img");o.addEventListener("load",(()=>{this._trailFill={image:o,opacity:1/e.length},t()})),o.addEventListener("error",(t=>{s(t.error)})),o.src=i.image}))},this._paintBase=t=>{this.draw((e=>yi(e,this.size,t)))},this._paintImage=(t,e)=>{this.draw((i=>gi(i,this.size,t,e)))},this._repairStyle=()=>{const t=this.element;t&&(this._safeMutationObserver((t=>t.disconnect())),this._initStyle(),this.initBackground(),this._safeMutationObserver((e=>e.observe(t,{attributes:!0}))))},this._resetOriginalStyle=()=>{const t=this.element,e=this._originalStyle;if(!t||!e)return;const i=t.style;i.position=e.position,i.zIndex=e.zIndex,i.top=e.top,i.left=e.left,i.width=e.width,i.height=e.height},this._safeMutationObserver=t=>{this._mutationObserver&&t(this._mutationObserver)},this._setFullScreenStyle=()=>{const t=this.element;if(!t)return;const e="important",i=t.style;i.setProperty("position","fixed",e),i.setProperty("z-index",this.container.actualOptions.fullScreen.zIndex.toString(10),e),i.setProperty("top","0",e),i.setProperty("left","0",e),i.setProperty("width","100%",e),i.setProperty("height","100%",e)},this.size={height:0,width:0},this._context=null,this._generated=!1,this._preDrawUpdaters=[],this._postDrawUpdaters=[],this._resizePlugins=[],this._colorPlugins=[]}get _fullScreen(){return this.container.actualOptions.fullScreen.enable}clear(){const t=this.container.actualOptions,e=t.particles.move.trail,i=this._trailFill;t.backgroundMask.enable?this.paint():e.enable&&e.length>0&&i?i.color?this._paintBase(Jt(i.color,i.opacity)):i.image&&this._paintImage(i.image,i.opacity):this.draw((t=>{bi(t,this.size)}))}destroy(){if(this.stop(),this._generated){const t=this.element;t&&t.remove()}else this._resetOriginalStyle();this._preDrawUpdaters=[],this._postDrawUpdaters=[],this._resizePlugins=[],this._colorPlugins=[]}draw(t){const e=this._context;if(e)return t(e)}drawParticle(t,e){if(t.spawning||t.destroyed)return;const i=t.getRadius();if(i<=0)return;const s=t.getFillColor(),o=t.getStrokeColor()??s;let[n,a]=this._getPluginParticleColors(t);n||(n=s),a||(a=o),(n||a)&&this.draw((s=>{const o=this.container,r=o.actualOptions,c=t.options.zIndex,l=(1-t.zIndexFactor)**c.opacityRate,h=t.bubble.opacity??t.opacity?.value??1,d=h*l,u=(t.strokeOpacity??h)*l,p={},f={fill:n?Zt(n,d):void 0};f.stroke=a?Zt(a,u):f.fill,this._applyPreDrawUpdaters(s,t,i,d,f,p),wi({container:o,context:s,particle:t,delta:e,colorStyles:f,backgroundMask:r.backgroundMask.enable,composite:r.backgroundMask.composite,radius:i*(1-t.zIndexFactor)**c.sizeRate,opacity:d,shadow:t.options.shadow,transform:p}),this._applyPostDrawUpdaters(t)}))}drawParticlePlugin(t,e,i){this.draw((s=>zi(s,t,e,i)))}drawPlugin(t,e){this.draw((i=>ki(i,t,e)))}async init(){this._safeMutationObserver((t=>t.disconnect())),this._mutationObserver=Y((t=>{for(const e of t)"attributes"===e.type&&"style"===e.attributeName&&this._repairStyle()})),this.resize(),this._initStyle(),this._initCover();try{await this._initTrail()}catch(t){$().error(t)}this.initBackground(),this._safeMutationObserver((t=>{this.element&&t.observe(this.element,{attributes:!0})})),this.initUpdaters(),this.initPlugins(),this.paint()}initBackground(){const t=this.container.actualOptions.background,e=this.element;if(!e)return;const i=e.style;if(i){if(t.color){const e=Vt(t.color);i.backgroundColor=e?Jt(e,t.opacity):""}else i.backgroundColor="";i.backgroundImage=t.image||"",i.backgroundPosition=t.position||"",i.backgroundRepeat=t.repeat||"",i.backgroundSize=t.size||""}}initPlugins(){this._resizePlugins=[];for(const[,t]of this.container.plugins)t.resize&&this._resizePlugins.push(t),(t.particleFillColor||t.particleStrokeColor)&&this._colorPlugins.push(t)}initUpdaters(){this._preDrawUpdaters=[],this._postDrawUpdaters=[];for(const t of this.container.particles.updaters)t.afterDraw&&this._postDrawUpdaters.push(t),(t.getColorStyles||t.getTransformValues||t.beforeDraw)&&this._preDrawUpdaters.push(t)}loadCanvas(t){this._generated&&this.element&&this.element.remove(),this._generated=t.dataset&&i in t.dataset?"true"===t.dataset[i]:this._generated,this.element=t,this.element.ariaHidden="true",this._originalStyle=st({},this.element.style),this.size.height=t.offsetHeight,this.size.width=t.offsetWidth,this._context=this.element.getContext("2d"),this._safeMutationObserver((t=>{this.element&&t.observe(this.element,{attributes:!0})})),this.container.retina.init(),this.initBackground()}paint(){const t=this.container.actualOptions;this.draw((e=>{t.backgroundMask.enable&&t.backgroundMask.cover?(bi(e,this.size),this._paintBase(this._coverColorStyle)):this._paintBase()}))}resize(){if(!this.element)return!1;const t=this.container,e=t.retina.pixelRatio,i=t.canvas.size,s=this.element.offsetWidth*e,o=this.element.offsetHeight*e;if(o===i.height&&s===i.width&&o===this.element.height&&s===this.element.width)return!1;const n={...i};return this.element.width=i.width=this.element.offsetWidth*e,this.element.height=i.height=this.element.offsetHeight*e,this.container.started&&(this.resizeFactor={width:i.width/n.width,height:i.height/n.height}),!0}stop(){this._safeMutationObserver((t=>t.disconnect())),this._mutationObserver=void 0,this.draw((t=>bi(t,this.size)))}async windowResize(){if(!this.element||!this.resize())return;const t=this.container,e=t.updateActualOptions();t.particles.setDensity(),this._applyResizePlugins(),e&&await t.refresh()}}function Si(t,e,i,s,o){if(s){let s={passive:!0};gt(o)?s.capture=o:void 0!==o&&(s=o),t.addEventListener(e,i,s)}else{const s=o;t.removeEventListener(e,i,s)}}class Oi{constructor(t){this.container=t,this._doMouseTouchClick=t=>{const e=this.container,i=e.actualOptions;if(this._canPush){const t=e.interactivity.mouse,s=t.position;if(!s)return;t.clickPosition={...s},t.clickTime=(new Date).getTime();dt(i.interactivity.events.onClick.mode,(t=>this.container.handleClickMode(t)))}"touchend"===t.type&&setTimeout((()=>this._mouseTouchFinish()),500)},this._handleThemeChange=t=>{const e=t,i=this.container,s=i.options,o=s.defaultThemes,n=e.matches?o.dark:o.light,a=s.themes.find((t=>t.name===n));a&&a.default.auto&&i.loadTheme(n)},this._handleVisibilityChange=()=>{const t=this.container,e=t.actualOptions;this._mouseTouchFinish(),e.pauseOnBlur&&(document&&document.hidden?(t.pageHidden=!0,t.pause()):(t.pageHidden=!1,t.getAnimationStatus()?t.play(!0):t.draw(!0)))},this._handleWindowResize=async()=>{this._resizeTimeout&&(clearTimeout(this._resizeTimeout),delete this._resizeTimeout),this._resizeTimeout=setTimeout((async()=>{const t=this.container.canvas;t&&await t.windowResize()}),1e3*this.container.actualOptions.interactivity.events.resize.delay)},this._manageInteractivityListeners=(t,e)=>{const i=this._handlers,n=this.container,a=n.actualOptions,u=n.interactivity.element;if(!u)return;const p=u,f=n.canvas.element;f&&(f.style.pointerEvents=p===f?"initial":"none"),(a.interactivity.events.onHover.enable||a.interactivity.events.onClick.enable)&&(Si(u,r,i.mouseMove,e),Si(u,c,i.touchStart,e),Si(u,h,i.touchMove,e),a.interactivity.events.onClick.enable?(Si(u,l,i.touchEndClick,e),Si(u,o,i.mouseUp,e),Si(u,s,i.mouseDown,e)):Si(u,l,i.touchEnd,e),Si(u,t,i.mouseLeave,e),Si(u,d,i.touchCancel,e))},this._manageListeners=t=>{const e=this._handlers,i=this.container,s=i.actualOptions.interactivity.detectsOn,o=i.canvas.element;let r=n;"window"===s?(i.interactivity.element=window,r=a):i.interactivity.element="parent"===s&&o?o.parentElement??o.parentNode:o,this._manageMediaMatch(t),this._manageResize(t),this._manageInteractivityListeners(r,t),document&&Si(document,p,e.visibilityChange,t,!1)},this._manageMediaMatch=t=>{const e=this._handlers,i=X("(prefers-color-scheme: dark)");i&&(void 0===i.addEventListener?void 0!==i.addListener&&(t?i.addListener(e.oldThemeChange):i.removeListener(e.oldThemeChange)):Si(i,"change",e.themeChange,t))},this._manageResize=t=>{const e=this._handlers,i=this.container;if(!i.actualOptions.interactivity.events.resize)return;if("undefined"==typeof ResizeObserver)return void Si(window,u,e.resize,t);const s=i.canvas.element;this._resizeObserver&&!t?(s&&this._resizeObserver.unobserve(s),this._resizeObserver.disconnect(),delete this._resizeObserver):!this._resizeObserver&&t&&s&&(this._resizeObserver=new ResizeObserver((async t=>{t.find((t=>t.target===s))&&await this._handleWindowResize()})),this._resizeObserver.observe(s))},this._mouseDown=()=>{const{interactivity:t}=this.container;if(!t)return;const{mouse:e}=t;e.clicking=!0,e.downPosition=e.position},this._mouseTouchClick=t=>{const e=this.container,i=e.actualOptions,{mouse:s}=e.interactivity;s.inside=!0;let o=!1;const n=s.position;if(n&&i.interactivity.events.onClick.enable){for(const[,t]of e.plugins)if(t.clickPositionValid&&(o=t.clickPositionValid(n),o))break;o||this._doMouseTouchClick(t),s.clicking=!1}},this._mouseTouchFinish=()=>{const t=this.container.interactivity;if(!t)return;const e=t.mouse;delete e.position,delete e.clickPosition,delete e.downPosition,t.status=n,e.inside=!1,e.clicking=!1},this._mouseTouchMove=t=>{const e=this.container,i=e.actualOptions,s=e.interactivity,o=e.canvas.element;if(!s||!s.element)return;let n;if(s.mouse.inside=!0,t.type.startsWith("pointer")){this._canPush=!0;const e=t;if(s.element===window){if(o){const t=o.getBoundingClientRect();n={x:e.clientX-t.left,y:e.clientY-t.top}}}else if("parent"===i.interactivity.detectsOn){const t=e.target,i=e.currentTarget;if(t&&i&&o){const s=t.getBoundingClientRect(),a=i.getBoundingClientRect(),r=o.getBoundingClientRect();n={x:e.offsetX+2*s.left-(a.left+r.left),y:e.offsetY+2*s.top-(a.top+r.top)}}else n={x:e.offsetX??e.clientX,y:e.offsetY??e.clientY}}else e.target===o&&(n={x:e.offsetX??e.clientX,y:e.offsetY??e.clientY})}else if(this._canPush="touchmove"!==t.type,o){const e=t,i=e.touches[e.touches.length-1],s=o.getBoundingClientRect();n={x:i.clientX-(s.left??0),y:i.clientY-(s.top??0)}}const a=e.retina.pixelRatio;n&&(n.x*=a,n.y*=a),s.mouse.position=n,s.status=r},this._touchEnd=t=>{const e=t,i=Array.from(e.changedTouches);for(const t of i)this._touches.delete(t.identifier);this._mouseTouchFinish()},this._touchEndClick=t=>{const e=t,i=Array.from(e.changedTouches);for(const t of i)this._touches.delete(t.identifier);this._mouseTouchClick(t)},this._touchStart=t=>{const e=t,i=Array.from(e.changedTouches);for(const t of i)this._touches.set(t.identifier,performance.now());this._mouseTouchMove(t)},this._canPush=!0,this._touches=new Map,this._handlers={mouseDown:()=>this._mouseDown(),mouseLeave:()=>this._mouseTouchFinish(),mouseMove:t=>this._mouseTouchMove(t),mouseUp:t=>this._mouseTouchClick(t),touchStart:t=>this._touchStart(t),touchMove:t=>this._mouseTouchMove(t),touchEnd:t=>this._touchEnd(t),touchCancel:t=>this._touchEnd(t),touchEndClick:t=>this._touchEndClick(t),visibilityChange:()=>this._handleVisibilityChange(),themeChange:t=>this._handleThemeChange(t),oldThemeChange:t=>this._handleThemeChange(t),resize:()=>{this._handleWindowResize()}}}addListeners(){this._manageListeners(!0)}removeListeners(){this._manageListeners(!1)}}class Ti{constructor(){this.color=new zt,this.color.value="",this.image="",this.position="",this.repeat="",this.size="",this.opacity=1}load(t){t&&(void 0!==t.color&&(this.color=zt.create(this.color,t.color)),void 0!==t.image&&(this.image=t.image),void 0!==t.position&&(this.position=t.position),void 0!==t.repeat&&(this.repeat=t.repeat),void 0!==t.size&&(this.size=t.size),void 0!==t.opacity&&(this.opacity=t.opacity))}}class Ri{constructor(){this.color=new zt,this.color.value="#fff",this.opacity=1}load(t){t&&(void 0!==t.color&&(this.color=zt.create(this.color,t.color)),void 0!==t.opacity&&(this.opacity=t.opacity))}}class Di{constructor(){this.composite="destination-out",this.cover=new Ri,this.enable=!1}load(t){if(t){if(void 0!==t.composite&&(this.composite=t.composite),void 0!==t.cover){const e=t.cover,i=bt(t.cover)?{color:t.cover}:t.cover;this.cover.load(void 0!==e.color?e:{color:i})}void 0!==t.enable&&(this.enable=t.enable)}}}class Ei{constructor(){this.enable=!0,this.zIndex=0}load(t){t&&(void 0!==t.enable&&(this.enable=t.enable),void 0!==t.zIndex&&(this.zIndex=t.zIndex))}}class Ii{constructor(){this.enable=!1,this.mode=[]}load(t){t&&(void 0!==t.enable&&(this.enable=t.enable),void 0!==t.mode&&(this.mode=t.mode))}}class Li{constructor(){this.selectors=[],this.enable=!1,this.mode=[],this.type="circle"}get el(){return this.elementId}set el(t){this.elementId=t}get elementId(){return this.ids}set elementId(t){this.ids=t}get ids(){return dt(this.selectors,(t=>t.replace("#","")))}set ids(t){this.selectors=dt(t,(t=>`#${t}`))}load(t){if(!t)return;const e=t.ids??t.elementId??t.el;void 0!==e&&(this.ids=e),void 0!==t.selectors&&(this.selectors=t.selectors),void 0!==t.enable&&(this.enable=t.enable),void 0!==t.mode&&(this.mode=t.mode),void 0!==t.type&&(this.type=t.type)}}class Ai{constructor(){this.enable=!1,this.force=2,this.smooth=10}load(t){t&&(void 0!==t.enable&&(this.enable=t.enable),void 0!==t.force&&(this.force=t.force),void 0!==t.smooth&&(this.smooth=t.smooth))}}class Fi{constructor(){this.enable=!1,this.mode=[],this.parallax=new Ai}load(t){t&&(void 0!==t.enable&&(this.enable=t.enable),void 0!==t.mode&&(this.mode=t.mode),this.parallax.load(t.parallax))}}class Bi{constructor(){this.delay=.5,this.enable=!0}load(t){void 0!==t&&(void 0!==t.delay&&(this.delay=t.delay),void 0!==t.enable&&(this.enable=t.enable))}}class qi{constructor(){this.onClick=new Ii,this.onDiv=new Li,this.onHover=new Fi,this.resize=new Bi}get onclick(){return this.onClick}set onclick(t){this.onClick=t}get ondiv(){return this.onDiv}set ondiv(t){this.onDiv=t}get onhover(){return this.onHover}set onhover(t){this.onHover=t}load(t){if(!t)return;this.onClick.load(t.onClick??t.onclick);const e=t.onDiv??t.ondiv;void 0!==e&&(this.onDiv=dt(e,(t=>{const e=new Li;return e.load(t),e}))),this.onHover.load(t.onHover??t.onhover),gt(t.resize)?this.resize.enable=t.resize:this.resize.load(t.resize)}}class Vi{constructor(t,e){this._engine=t,this._container=e}load(t){if(!t)return;if(!this._container)return;const e=this._engine.plugins.interactors.get(this._container);if(e)for(const i of e)i.loadModeOptions&&i.loadModeOptions(this,t)}}class Hi{constructor(t,e){this.detectsOn="window",this.events=new qi,this.modes=new Vi(t,e)}get detect_on(){return this.detectsOn}set detect_on(t){this.detectsOn=t}load(t){if(!t)return;const e=t.detectsOn??t.detect_on;void 0!==e&&(this.detectsOn=e),this.events.load(t.events),this.modes.load(t.modes)}}class Ui{load(t){t&&(t.position&&(this.position={x:t.position.x??50,y:t.position.y??50,mode:t.position.mode??"percent"}),t.options&&(this.options=st({},t.options)))}}class Wi{constructor(){this.maxWidth=1/0,this.options={},this.mode="canvas"}load(t){t&&(void 0!==t.maxWidth&&(this.maxWidth=t.maxWidth),void 0!==t.mode&&("screen"===t.mode?this.mode="screen":this.mode="canvas"),void 0!==t.options&&(this.options=st({},t.options)))}}class $i{constructor(){this.auto=!1,this.mode="any",this.value=!1}load(t){t&&(void 0!==t.auto&&(this.auto=t.auto),void 0!==t.mode&&(this.mode=t.mode),void 0!==t.value&&(this.value=t.value))}}class Gi{constructor(){this.name="",this.default=new $i}load(t){t&&(void 0!==t.name&&(this.name=t.name),this.default.load(t.default),void 0!==t.options&&(this.options=st({},t.options)))}}class ji{constructor(t,e){this._findDefaultTheme=t=>this.themes.find((e=>e.default.value&&e.default.mode===t))??this.themes.find((t=>t.default.value&&"any"===t.default.mode)),this._importPreset=t=>{this.load(this._engine.plugins.getPreset(t))},this._engine=t,this._container=e,this.autoPlay=!0,this.background=new Ti,this.backgroundMask=new Di,this.defaultThemes={},this.delay=0,this.fullScreen=new Ei,this.detectRetina=!0,this.duration=0,this.fpsLimit=120,this.interactivity=new Hi(t,e),this.manualParticles=[],this.particles=Xe(this._engine,this._container),this.pauseOnBlur=!0,this.pauseOnOutsideViewport=!0,this.responsive=[],this.smooth=!1,this.style={},this.themes=[],this.zLayers=100}get backgroundMode(){return this.fullScreen}set backgroundMode(t){this.fullScreen.load(t)}get fps_limit(){return this.fpsLimit}set fps_limit(t){this.fpsLimit=t}get retina_detect(){return this.detectRetina}set retina_detect(t){this.detectRetina=t}load(t){if(!t)return;void 0!==t.preset&&dt(t.preset,(t=>this._importPreset(t))),void 0!==t.autoPlay&&(this.autoPlay=t.autoPlay),void 0!==t.delay&&(this.delay=O(t.delay));const e=t.detectRetina??t.retina_detect;void 0!==e&&(this.detectRetina=e),void 0!==t.duration&&(this.duration=O(t.duration));const i=t.fpsLimit??t.fps_limit;void 0!==i&&(this.fpsLimit=i),void 0!==t.pauseOnBlur&&(this.pauseOnBlur=t.pauseOnBlur),void 0!==t.pauseOnOutsideViewport&&(this.pauseOnOutsideViewport=t.pauseOnOutsideViewport),void 0!==t.zLayers&&(this.zLayers=t.zLayers),this.background.load(t.background);const s=t.fullScreen??t.backgroundMode;gt(s)?this.fullScreen.enable=s:this.fullScreen.load(s),this.backgroundMask.load(t.backgroundMask),this.interactivity.load(t.interactivity),t.manualParticles&&(this.manualParticles=t.manualParticles.map((t=>{const e=new Ui;return e.load(t),e}))),this.particles.load(t.particles),this.style=st(this.style,t.style),this._engine.plugins.loadOptions(this,t),void 0!==t.smooth&&(this.smooth=t.smooth);const o=this._engine.plugins.interactors.get(this._container);if(o)for(const e of o)e.loadOptions&&e.loadOptions(this,t);if(void 0!==t.responsive)for(const e of t.responsive){const t=new Wi;t.load(e),this.responsive.push(t)}if(this.responsive.sort(((t,e)=>t.maxWidth-e.maxWidth)),void 0!==t.themes)for(const e of t.themes){const t=this.themes.find((t=>t.name===e.name));if(t)t.load(e);else{const t=new Gi;t.load(e),this.themes.push(t)}}this.defaultThemes.dark=this._findDefaultTheme("dark")?.name,this.defaultThemes.light=this._findDefaultTheme("light")?.name}setResponsive(t,e,i){this.load(i);const s=this.responsive.find((i=>"screen"===i.mode&&screen?i.maxWidth>screen.availWidth:i.maxWidth*e>t));return this.load(s?.options),s?.maxWidth}setTheme(t){if(t){const e=this.themes.find((e=>e.name===t));e&&this.load(e.options)}else{const t=X("(prefers-color-scheme: dark)"),e=t&&t.matches,i=this._findDefaultTheme(e?"dark":"light");i&&this.load(i.options)}}}class Ni{constructor(t,e){this.container=e,this._engine=t,this._interactors=t.plugins.getInteractors(this.container,!0),this._externalInteractors=[],this._particleInteractors=[]}async externalInteract(t){for(const e of this._externalInteractors)e.isEnabled()&&await e.interact(t)}handleClickMode(t){for(const e of this._externalInteractors)e.handleClickMode&&e.handleClickMode(t)}init(){this._externalInteractors=[],this._particleInteractors=[];for(const t of this._interactors){switch(t.type){case"external":this._externalInteractors.push(t);break;case"particles":this._particleInteractors.push(t)}t.init()}}async particlesInteract(t,e){for(const i of this._externalInteractors)i.clear(t,e);for(const i of this._particleInteractors)i.isEnabled(t)&&await i.interact(t,e)}async reset(t){for(const e of this._externalInteractors)e.isEnabled()&&e.reset(t);for(const e of this._particleInteractors)e.isEnabled(t)&&e.reset(t)}}const Xi=t=>{if(!J(t.outMode,t.checkModes))return;const e=2*t.radius;t.coord>t.maxCoord-e?t.setCb(-t.radius):t.coord{for(const[,s]of t.plugins){const t=void 0!==s.particlePosition?s.particlePosition(e,this):void 0;if(t)return v.create(t.x,t.y,i)}const o=q({size:t.canvas.size,position:e}),n=v.create(o.x,o.y,i),a=this.getRadius(),r=this.options.move.outModes,c=e=>{Xi({outMode:e,checkModes:["bounce","bounce-horizontal"],coord:n.x,maxCoord:t.canvas.size.width,setCb:t=>n.x+=t,radius:a})},l=e=>{Xi({outMode:e,checkModes:["bounce","bounce-vertical"],coord:n.y,maxCoord:t.canvas.size.height,setCb:t=>n.y+=t,radius:a})};return c(r.left??r.default),c(r.right??r.default),l(r.top??r.default),l(r.bottom??r.default),this._checkOverlap(n,s)?this._calcPosition(t,void 0,i,s+1):n},this._calculateVelocity=()=>{const t=I(this.direction).copy(),e=this.options.move;if("inside"===e.direction||"outside"===e.direction)return t;const i=Math.PI/180*P(e.angle.value),s=Math.PI/180*P(e.angle.offset),o={left:s-i/2,right:s+i/2};return e.straight||(t.angle+=M(O(o.left,o.right))),e.random&&"number"==typeof e.speed&&(t.length*=_()),t},this._checkOverlap=(t,e=0)=>{const i=this.options.collisions,s=this.getRadius();if(!i.enable)return!1;const o=i.overlap;if(o.enable)return!1;const n=o.retries;if(n>=0&&e>n)throw new Error(`${f} particle is overlapping and can't be placed`);return!!this.container.particles.find((e=>D(t,e.position){if(!t||!this.roll||!this.backColor&&!this.roll.alter)return t;const e=this.roll.horizontal&&this.roll.vertical?2:1,i=this.roll.horizontal?Math.PI/2:0;return Math.floor(((this.roll.angle??0)+i)/(Math.PI/e))%2?this.backColor?this.backColor:this.roll.alter?Mi(t,this.roll.alter.type,this.roll.alter.value):t:t},this._initPosition=t=>{const e=this.container,i=P(this.options.zIndex.value);this.position=this._calcPosition(e,t,k(i,0,e.zLayers)),this.initialPosition=this.position.copy();const s=e.canvas.size;switch(this.moveCenter={...mt(this.options.move.center,s),radius:this.options.move.center.radius??0,mode:this.options.move.center.mode??"percent"},this.direction=E(this.options.move.direction,this.position,this.moveCenter),this.options.move.direction){case"inside":this.outType="inside";break;case"outside":this.outType="outside"}this.offset=m.origin},this._loadShapeData=(t,e)=>{const i=t.options[this.shape];if(i)return st({close:t.close,fill:t.fill},ut(i,this.id,e))},this._engine=t,this.init(e,s,o,n)}destroy(t){if(this.unbreakable||this.destroyed)return;this.destroyed=!0,this.bubble.inRange=!1,this.slow.inRange=!1;const e=this.container,i=this.pathGenerator;for(const[,i]of e.plugins)i.particleDestroyed&&i.particleDestroyed(this,t);for(const i of e.particles.updaters)i.particleDestroyed&&i.particleDestroyed(this,t);i&&i.reset(this)}draw(t){const e=this.container;for(const[,i]of e.plugins)e.canvas.drawParticlePlugin(i,this,t);e.canvas.drawParticle(this,t)}getFillColor(){return this._getRollColor(this.bubble.color??ee(this.color))}getMass(){return this.getRadius()**2*Math.PI/2}getPosition(){return{x:this.position.x+this.offset.x,y:this.position.y+this.offset.y,z:this.position.z}}getRadius(){return this.bubble.radius??this.size.value}getStrokeColor(){return this._getRollColor(this.bubble.color??ee(this.strokeColor))}init(t,e,i,s){const o=this.container,n=this._engine;this.id=t,this.group=s,this.fill=!0,this.pathRotation=!1,this.close=!0,this.lastPathTime=0,this.destroyed=!1,this.unbreakable=!1,this.rotation=0,this.misplaced=!1,this.retina={maxDistance:{}},this.outType="normal",this.ignoresResizeRatio=!0;const a=o.retina.pixelRatio,r=o.actualOptions,c=Xe(this._engine,o,r.particles),l=c.shape.type,{reduceDuplicates:h}=c;this.shape=ut(l,this.id,h);const d=c.shape;if(i&&i.shape&&i.shape.type){const t=ut(i.shape.type,this.id,h);t&&(this.shape=t,d.load(i.shape))}this.shapeData=this._loadShapeData(d,h),c.load(i);const u=this.shapeData;u&&c.load(u.particles);const p=new Hi(n,o);p.load(o.actualOptions.interactivity),p.load(c.interactivity),this.interactivity=p,this.fill=u?.fill??c.shape.fill,this.close=u?.close??c.shape.close,this.options=c;const f=this.options.move.path;this.pathDelay=1e3*T(f.delay),f.generator&&(this.pathGenerator=this._engine.plugins.getPathGenerator(f.generator),this.pathGenerator&&o.addPath(f.generator,this.pathGenerator)&&this.pathGenerator.init(o)),o.retina.initParticle(this),this.size=ft(this.options.size,a),this.bubble={inRange:!1},this.slow={inRange:!1,factor:1},this._initPosition(e),this.initialVelocity=this._calculateVelocity(),this.velocity=this.initialVelocity.copy(),this.moveDecay=1-P(this.options.move.decay);const v=o.particles;v.needsSort=v.needsSort||v.lastZIndex=-t&&i.y>=-t&&i.y<=e.height+t&&i.x<=e.width+t}isVisible(){return!this.destroyed&&!this.spawning&&this.isInsideCanvas()}reset(){for(const t of this.container.particles.updaters)t.reset&&t.reset(this)}}class Ji{constructor(t,e){this.position=t,this.particle=e}}class Zi{constructor(t,e){this.position={x:t,y:e}}}class Qi extends Zi{constructor(t,e,i,s){super(t,e),this.size={height:s,width:i}}contains(t){const e=this.size.width,i=this.size.height,s=this.position;return t.x>=s.x&&t.x<=s.x+e&&t.y>=s.y&&t.y<=s.y+i}intersects(t){t instanceof Ki&&t.intersects(this);const e=this.size.width,i=this.size.height,s=this.position,o=t.position,n=t instanceof Qi?t.size:{width:0,height:0},a=n.width,r=n.height;return o.xs.x&&o.ys.y}}class Ki extends Zi{constructor(t,e,i){super(t,e),this.radius=i}contains(t){return D(t,this.position)<=this.radius}intersects(t){const e=this.position,i=t.position,s=Math.abs(i.x-e.x),o=Math.abs(i.y-e.y),n=this.radius;if(t instanceof Ki){return n+t.radius>Math.sqrt(s**2+o**2)}if(t instanceof Qi){const{width:e,height:i}=t.size;return Math.pow(s-e,2)+Math.pow(o-i,2)<=n**2||s<=n+e&&o<=n+i||s<=e||o<=i}return!1}}class ts{constructor(t,e){this.rectangle=t,this.capacity=e,this._subdivide=()=>{const{x:t,y:e}=this.rectangle.position,{width:i,height:s}=this.rectangle.size,{capacity:o}=this;for(let n=0;n<4;n++)this._subs.push(new ts(new Qi(t+i/2*(n%2),e+s/2*(Math.round(n/2)-n%2),i/2,s/2),o));this._divided=!0},this._points=[],this._divided=!1,this._subs=[]}insert(t){return!!this.rectangle.contains(t.position)&&(this._points.lengthe.insert(t)))))}query(t,e,i){const s=i||[];if(!t.intersects(this.rectangle))return[];for(const i of this._points)!t.contains(i.position)&&D(t.position,i.position)>i.particle.getRadius()&&(!e||e(i.particle))||s.push(i.particle);if(this._divided)for(const i of this._subs)i.query(t,e,s);return s}queryCircle(t,e,i){return this.query(new Ki(t.x,t.y,e),i)}queryRectangle(t,e,i){return this.query(new Qi(t.x,t.y,e.width,e.height),i)}}const es=t=>new Qi(-t.width/4,-t.height/4,3*t.width/2,3*t.height/2);class is{constructor(t,e){this._applyDensity=(t,e,i)=>{if(!t.number.density?.enable)return;const s=t.number,o=this._initDensityFactor(s.density),n=s.value,a=s.limit>0?s.limit:n,r=Math.min(n,a)*o+e,c=Math.min(this.count,this.filter((t=>t.group===i)).length);this.limit=s.limit*o,cr&&this.removeQuantity(c-r,i)},this._initDensityFactor=t=>{const e=this._container;if(!e.canvas.element||!t.enable)return 1;const i=e.canvas.element,s=e.retina.pixelRatio;return i.width*i.height/(t.factor*s**2*t.area)},this._pushParticle=(t,e,i,s)=>{try{let o=this.pool.pop();o?o.init(this._nextId,t,e,i):o=new Yi(this._engine,this._nextId,this._container,t,e,i);let n=!0;if(s&&(n=s(o)),!n)return;return this._array.push(o),this._zArray.push(o),this._nextId++,this._engine.dispatchEvent("particleAdded",{container:this._container,data:{particle:o}}),o}catch(t){return void $().warning(`${f} adding particle: ${t}`)}},this._removeParticle=(t,e,i)=>{const s=this._array[t];if(!s||s.group!==e)return!1;s.destroy(i);const o=this._zArray.indexOf(s);return this._array.splice(t,1),this._zArray.splice(o,1),this.pool.push(s),this._engine.dispatchEvent("particleRemoved",{container:this._container,data:{particle:s}}),!0},this._engine=t,this._container=e,this._nextId=0,this._array=[],this._zArray=[],this.pool=[],this.limit=0,this.needsSort=!1,this.lastZIndex=0,this._interactionManager=new Ni(t,e);const i=e.canvas.size;this.quadTree=new ts(es(i),4),this.movers=this._engine.plugins.getMovers(e,!0),this.updaters=this._engine.plugins.getUpdaters(e,!0)}get count(){return this._array.length}addManualParticles(){const t=this._container,e=t.actualOptions;for(const i of e.manualParticles)this.addParticle(i.position?mt(i.position,t.canvas.size):void 0,i.options)}addParticle(t,e,i,s){const o=this._container.actualOptions.particles.number.limit;if(o>0){const t=this.count+1-o;t>0&&this.removeQuantity(t)}return this._pushParticle(t,e,i,s)}clear(){this._array=[],this._zArray=[]}destroy(){this._array=[],this._zArray=[],this.movers=[],this.updaters=[]}async draw(t){const e=this._container;e.canvas.clear(),await this.update(t);for(const[,i]of e.plugins)e.canvas.drawPlugin(i,t);for(const e of this._zArray)e.draw(t)}filter(t){return this._array.filter(t)}find(t){return this._array.find(t)}handleClickMode(t){this._interactionManager.handleClickMode(t)}init(){const t=this._container,e=t.actualOptions;this.lastZIndex=0,this.needsSort=!1;let i=!1;this.updaters=this._engine.plugins.getUpdaters(t,!0),this._interactionManager.init();for(const[,e]of t.plugins)if(void 0!==e.particlesInitialization&&(i=e.particlesInitialization()),i)break;this._interactionManager.init();for(const[,e]of t.pathGenerators)e.init(t);if(this.addManualParticles(),!i){for(const t in e.particles.groups){const i=e.particles.groups[t];for(let s=this.count,o=0;othis.count)return;let o=0;for(let n=t;o!i.has(t);this._array=this.filter(t),this._zArray=this._zArray.filter(t),this.pool.push(...i)}await this._interactionManager.externalInteract(t);for(const e of this._array){for(const i of this.updaters)i.update(e,t);e.destroyed||e.spawning||await this._interactionManager.particlesInteract(e,t)}if(delete e.canvas.resizeFactor,this.needsSort){const t=this._zArray;t.sort(((t,e)=>e.position.z-t.position.z||t.id-e.id)),this.lastZIndex=t[t.length-1].position.z,this.needsSort=!1}}}class ss{constructor(t){this.container=t,this.pixelRatio=1,this.reduceFactor=1}init(){const t=this.container,e=t.actualOptions;this.pixelRatio=!e.detectRetina||j()?1:window.devicePixelRatio,this.reduceFactor=1;const i=this.pixelRatio;if(t.canvas.element){const e=t.canvas.element;t.canvas.size.width=e.offsetWidth*i,t.canvas.size.height=e.offsetHeight*i}const s=e.particles,o=s.move;this.attractDistance=P(o.attract.distance)*i,this.maxSpeed=P(o.gravity.maxSpeed)*i,this.sizeAnimationSpeed=P(s.size.animation.speed)*i}initParticle(t){const e=t.options,i=this.pixelRatio,s=e.move,o=s.distance,n=t.retina;n.attractDistance=P(s.attract.distance)*i,n.moveDrift=P(s.drift)*i,n.moveSpeed=P(s.speed)*i,n.sizeAnimationSpeed=P(e.size.animation.speed)*i;const a=n.maxDistance;a.horizontal=void 0!==o.horizontal?o.horizontal*i:void 0,a.vertical=void 0!==o.vertical?o.vertical*i:void 0,n.maxSpeed=P(s.gravity.maxSpeed)*i}}function os(t){return t&&!t.destroyed}function ns(t,e,...i){const s=new ji(t,e);return Ne(s,...i),s}const as={generate:t=>t.velocity,init:()=>{},update:()=>{},reset:()=>{}};class rs{constructor(t,e,i){this.id=e,this._intersectionManager=t=>{if(os(this)&&this.actualOptions.pauseOnOutsideViewport)for(const e of t)e.target===this.interactivity.element&&(e.isIntersecting?this.play:this.pause)()},this._nextFrame=async t=>{try{if(!this.smooth&&void 0!==this.lastFrameTime&&t1e3)return void this.draw(!1);if(await this.particles.draw(e),!this.alive())return void this.destroy();this.getAnimationStatus()&&this.draw(!1)}catch(t){$().error(`${f} in animation loop`,t)}},this._engine=t,this.fpsLimit=120,this.smooth=!1,this._delay=0,this._duration=0,this._lifeTime=0,this._firstStart=!0,this.started=!1,this.destroyed=!1,this._paused=!0,this.lastFrameTime=0,this.zLayers=100,this.pageHidden=!1,this._sourceOptions=i,this._initialSourceOptions=i,this.retina=new ss(this),this.canvas=new Ci(this),this.particles=new is(this._engine,this),this.pathGenerators=new Map,this.interactivity={mouse:{clicking:!1,inside:!1}},this.plugins=new Map,this.drawers=new Map,this._options=ns(this._engine,this),this.actualOptions=ns(this._engine,this),this._eventListeners=new Oi(this),"undefined"!=typeof IntersectionObserver&&IntersectionObserver&&(this._intersectionObserver=new IntersectionObserver((t=>this._intersectionManager(t)))),this._engine.dispatchEvent("containerBuilt",{container:this})}get options(){return this._options}get sourceOptions(){return this._sourceOptions}addClickHandler(t){if(!os(this))return;const e=this.interactivity.element;if(!e)return;const i=(e,i,s)=>{if(!os(this))return;const o=this.retina.pixelRatio,n={x:i.x*o,y:i.y*o},a=this.particles.quadTree.queryCircle(n,s*o);t(e,a)};let s=!1,o=!1;e.addEventListener("click",(t=>{if(!os(this))return;const e=t,s={x:e.offsetX||e.clientX,y:e.offsetY||e.clientY};i(t,s,1)})),e.addEventListener("touchstart",(()=>{os(this)&&(s=!0,o=!1)})),e.addEventListener("touchmove",(()=>{os(this)&&(o=!0)})),e.addEventListener("touchend",(t=>{if(os(this)){if(s&&!o){const e=t;let s=e.touches[e.touches.length-1];if(!s&&(s=e.changedTouches[e.changedTouches.length-1],!s))return;const o=this.canvas.element,n=o?o.getBoundingClientRect():void 0,a={x:s.clientX-(n?n.left:0),y:s.clientY-(n?n.top:0)};i(t,a,Math.max(s.radiusX,s.radiusY))}s=!1,o=!1}})),e.addEventListener("touchcancel",(()=>{os(this)&&(s=!1,o=!1)}))}addLifeTime(t){this._lifeTime+=t}addPath(t,e,i=!1){return!(!os(this)||!i&&this.pathGenerators.has(t))&&(this.pathGenerators.set(t,e??as),!0)}alive(){return!this._duration||this._lifeTime<=this._duration}destroy(){if(!os(this))return;this.stop(),this.particles.destroy(),this.canvas.destroy();for(const[,t]of this.drawers)t.destroy&&t.destroy(this);for(const t of this.drawers.keys())this.drawers.delete(t);this._engine.plugins.destroy(this),this.destroyed=!0;const t=this._engine.dom(),e=t.findIndex((t=>t===this));e>=0&&t.splice(e,1),this._engine.dispatchEvent("containerDestroyed",{container:this})}draw(t){if(!os(this))return;let e=t;this._drawAnimationFrame=requestAnimationFrame((async t=>{e&&(this.lastFrameTime=void 0,e=!1),await this._nextFrame(t)}))}async export(t,e={}){for(const[,i]of this.plugins){if(!i.export)continue;const s=await i.export(t,e);if(s.supported)return s.blob}$().error(`${f} - Export plugin with type ${t} not found`)}getAnimationStatus(){return!this._paused&&!this.pageHidden&&os(this)}handleClickMode(t){if(os(this)){this.particles.handleClickMode(t);for(const[,e]of this.plugins)e.handleClickMode&&e.handleClickMode(t)}}async init(){if(!os(this))return;const t=this._engine.plugins.getSupportedShapes();for(const e of t){const t=this._engine.plugins.getShapeDrawer(e);t&&this.drawers.set(e,t)}this._options=ns(this._engine,this,this._initialSourceOptions,this.sourceOptions),this.actualOptions=ns(this._engine,this,this._options);const e=this._engine.plugins.getAvailablePlugins(this);for(const[t,i]of e)this.plugins.set(t,i);this.retina.init(),await this.canvas.init(),this.updateActualOptions(),this.canvas.initBackground(),this.canvas.resize(),this.zLayers=this.actualOptions.zLayers,this._duration=1e3*P(this.actualOptions.duration),this._delay=1e3*P(this.actualOptions.delay),this._lifeTime=0,this.fpsLimit=this.actualOptions.fpsLimit>0?this.actualOptions.fpsLimit:120,this.smooth=this.actualOptions.smooth;for(const[,t]of this.drawers)t.init&&await t.init(this);for(const[,t]of this.plugins)t.init&&await t.init();this._engine.dispatchEvent("containerInit",{container:this}),this.particles.init(),this.particles.setDensity();for(const[,t]of this.plugins)t.particlesSetup&&t.particlesSetup();this._engine.dispatchEvent("particlesSetup",{container:this})}async loadTheme(t){os(this)&&(this._currentTheme=t,await this.refresh())}pause(){if(os(this)&&(void 0!==this._drawAnimationFrame&&(cancelAnimationFrame(this._drawAnimationFrame),delete this._drawAnimationFrame),!this._paused)){for(const[,t]of this.plugins)t.pause&&t.pause();this.pageHidden||(this._paused=!0),this._engine.dispatchEvent("containerPaused",{container:this})}}play(t){if(!os(this))return;const e=this._paused||t;if(!this._firstStart||this.actualOptions.autoPlay){if(this._paused&&(this._paused=!1),e)for(const[,t]of this.plugins)t.play&&t.play();this._engine.dispatchEvent("containerPlay",{container:this}),this.draw(e||!1)}else this._firstStart=!1}async refresh(){if(os(this))return this.stop(),this.start()}async reset(){if(os(this))return this._initialSourceOptions=void 0,this._options=ns(this._engine,this),this.actualOptions=ns(this._engine,this,this._options),this.refresh()}setNoise(t,e,i){os(this)&&this.setPath(t,e,i)}setPath(t,e,i){if(!t||!os(this))return;const s={...as};if(xt(t))s.generate=t,e&&(s.init=e),i&&(s.update=i);else{const e=s;s.generate=t.generate||e.generate,s.init=t.init||e.init,s.update=t.update||e.update}this.addPath("default",s,!0)}async start(){os(this)&&!this.started&&(await this.init(),this.started=!0,await new Promise((t=>{this._delayTimeout=setTimeout((async()=>{this._eventListeners.addListeners(),this.interactivity.element instanceof HTMLElement&&this._intersectionObserver&&this._intersectionObserver.observe(this.interactivity.element);for(const[,t]of this.plugins)t.start&&await t.start();this._engine.dispatchEvent("containerStarted",{container:this}),this.play(),t()}),this._delay)})))}stop(){if(os(this)&&this.started){this._delayTimeout&&(clearTimeout(this._delayTimeout),delete this._delayTimeout),this._firstStart=!0,this.started=!1,this._eventListeners.removeListeners(),this.pause(),this.particles.clear(),this.canvas.stop(),this.interactivity.element instanceof HTMLElement&&this._intersectionObserver&&this._intersectionObserver.unobserve(this.interactivity.element);for(const[,t]of this.plugins)t.stop&&t.stop();for(const t of this.plugins.keys())this.plugins.delete(t);this._sourceOptions=this._options,this._engine.dispatchEvent("containerStopped",{container:this})}}updateActualOptions(){this.actualOptions.responsive=[];const t=this.actualOptions.setResponsive(this.canvas.size.width,this.retina.pixelRatio,this._options);return this.actualOptions.setTheme(this._currentTheme),this.responsiveMaxWidth!==t&&(this.responsiveMaxWidth=t,!0)}}class cs{constructor(){this._listeners=new Map}addEventListener(t,e){this.removeEventListener(t,e);let i=this._listeners.get(t);i||(i=[],this._listeners.set(t,i)),i.push(e)}dispatchEvent(t,e){const i=this._listeners.get(t);i&&i.forEach((t=>t(e)))}hasEventListener(t){return!!this._listeners.get(t)}removeAllEventListeners(t){t?this._listeners.delete(t):this._listeners=new Map}removeEventListener(t,e){const i=this._listeners.get(t);if(!i)return;const s=i.length,o=i.indexOf(e);o<0||(1===s?this._listeners.delete(t):i.splice(o,1))}}function ls(t,e,i,s=!1){let o=e.get(t);return o&&!s||(o=[...i.values()].map((e=>e(t))),e.set(t,o)),o}class hs{constructor(t){this._engine=t,this.plugins=[],this._initializers={interactors:new Map,movers:new Map,updaters:new Map},this.interactors=new Map,this.movers=new Map,this.updaters=new Map,this.presets=new Map,this.drawers=new Map,this.pathGenerators=new Map}addInteractor(t,e){this._initializers.interactors.set(t,e)}addParticleMover(t,e){this._initializers.movers.set(t,e)}addParticleUpdater(t,e){this._initializers.updaters.set(t,e)}addPathGenerator(t,e){!this.getPathGenerator(t)&&this.pathGenerators.set(t,e)}addPlugin(t){!this.getPlugin(t.id)&&this.plugins.push(t)}addPreset(t,e,i=!1){(i||!this.getPreset(t))&&this.presets.set(t,e)}addShapeDrawer(t,e){dt(t,(t=>{!this.getShapeDrawer(t)&&this.drawers.set(t,e)}))}destroy(t){this.updaters.delete(t),this.movers.delete(t),this.interactors.delete(t)}getAvailablePlugins(t){const e=new Map;for(const i of this.plugins)i.needsPlugin(t.actualOptions)&&e.set(i.id,i.getPlugin(t));return e}getInteractors(t,e=!1){return ls(t,this.interactors,this._initializers.interactors,e)}getMovers(t,e=!1){return ls(t,this.movers,this._initializers.movers,e)}getPathGenerator(t){return this.pathGenerators.get(t)}getPlugin(t){return this.plugins.find((e=>e.id===t))}getPreset(t){return this.presets.get(t)}getShapeDrawer(t){return this.drawers.get(t)}getSupportedShapes(){return this.drawers.keys()}getUpdaters(t,e=!1){return ls(t,this.updaters,this._initializers.updaters,e)}loadOptions(t,e){for(const i of this.plugins)i.loadOptions(t,e)}loadParticlesOptions(t,e,...i){const s=this.updaters.get(t);if(s)for(const t of s)t.loadOptions&&t.loadOptions(e,...i)}}class ds{constructor(){this._configs=new Map,this._domArray=[],this._eventDispatcher=new cs,this._initialized=!1,this.plugins=new hs(this)}get configs(){const t={};for(const[e,i]of this._configs)t[e]=i;return t}get version(){return"2.12.0"}addConfig(t,e){bt(t)?e&&(e.name=t,this._configs.set(t,e)):this._configs.set(t.name??"default",t)}addEventListener(t,e){this._eventDispatcher.addEventListener(t,e)}async addInteractor(t,e,i=!0){this.plugins.addInteractor(t,e),await this.refresh(i)}async addMover(t,e,i=!0){this.plugins.addParticleMover(t,e),await this.refresh(i)}async addParticleUpdater(t,e,i=!0){this.plugins.addParticleUpdater(t,e),await this.refresh(i)}async addPathGenerator(t,e,i=!0){this.plugins.addPathGenerator(t,e),await this.refresh(i)}async addPlugin(t,e=!0){this.plugins.addPlugin(t),await this.refresh(e)}async addPreset(t,e,i=!1,s=!0){this.plugins.addPreset(t,e,i),await this.refresh(s)}async addShape(t,e,i,s,o,n=!0){let a,r,c,l,h=n;gt(i)?(h=i,r=void 0):r=i,gt(s)?(h=s,c=void 0):c=s,gt(o)?(h=o,l=void 0):l=o,a=xt(e)?{afterEffect:c,destroy:l,draw:e,init:r}:e,this.plugins.addShapeDrawer(t,a),await this.refresh(h)}dispatchEvent(t,e){this._eventDispatcher.dispatchEvent(t,e)}dom(){return this._domArray}domItem(t){const e=this.dom(),i=e[t];if(i&&!i.destroyed)return i;e.splice(t,1)}init(){this._initialized||(this._initialized=!0)}async load(t,e){return this.loadFromArray(t,e)}async loadFromArray(t,e,i){let s;return!function(t){return!!((e=t).id||e.element||e.url||e.options);var e}(t)?(s={},bt(t)?s.id=t:s.options=t,wt(e)?s.index=e:s.options=e??s.options,s.index=i??s.index):s=t,this._loadParams(s)}async loadJSON(t,e,i){let s,o;return wt(e)||void 0===e?s=t:(o=t,s=e),this._loadParams({id:o,url:s,index:i})}async refresh(t=!0){t&&this.dom().forEach((t=>t.refresh()))}removeEventListener(t,e){this._eventDispatcher.removeEventListener(t,e)}async set(t,e,i,s){const o={index:s};return bt(t)?o.id=t:o.element=t,e instanceof HTMLElement?o.element=e:o.options=e,wt(i)?o.index=i:o.options=i??o.options,this._loadParams(o)}async setJSON(t,e,i,s){const o={};return t instanceof HTMLElement?(o.element=t,o.url=e,o.index=i):(o.id=t,o.element=e,o.url=i,o.index=s),this._loadParams(o)}setOnClickHandler(t){const e=this.dom();if(!e.length)throw new Error(`${f} can only set click handlers after calling tsParticles.load()`);for(const i of e)i.addClickHandler(t)}async _loadParams(t){const e=t.id??`tsparticles${Math.floor(1e4*_())}`,{index:s,url:o}=t,n=o?await async function(t){const e=ut(t.url,t.index);if(!e)return t.fallback;const i=await fetch(e);return i.ok?i.json():($().error(`${f} ${i.status} while retrieving config file`),t.fallback)}({fallback:t.options,url:o,index:s}):t.options;let a=t.element??document.getElementById(e);a||(a=document.createElement("div"),a.id=e,document.body.append(a));const r=ut(n,s),c=this.dom(),l=c.findIndex((t=>t.id===e));if(l>=0){const t=this.domItem(l);t&&!t.destroyed&&(t.destroy(),c.splice(l,1))}let h;if("canvas"===a.tagName.toLowerCase())h=a,h.dataset[i]="false";else{const t=a.getElementsByTagName("canvas");t.length?(h=t[0],h.dataset[i]="false"):(h=document.createElement("canvas"),h.dataset[i]="true",a.appendChild(h))}h.style.width||(h.style.width="100%"),h.style.height||(h.style.height="100%");const d=new rs(this,e,r);return l>=0?c.splice(l,0,d):c.push(d),d.canvas.loadCanvas(h),await d.start(),d}}class us{constructor(){this.key="hsl",this.stringPrefix="hsl"}handleColor(t){const e=t.value.hsl??t.value;if(void 0!==e.h&&void 0!==e.s&&void 0!==e.l)return Nt(e)}handleRangeColor(t){const e=t.value.hsl??t.value;if(void 0!==e.h&&void 0!==e.l)return Nt({h:P(e.h),l:P(e.l),s:P(e.s)})}parseString(t){if(!t.startsWith("hsl"))return;const e=/hsla?\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*(,\s*([\d.%]+)\s*)?\)/i.exec(t);return e?Xt({a:e.length>4?H(e[5]):1,h:parseInt(e[1],10),l:parseInt(e[3],10),s:parseInt(e[2],10)}):void 0}}class ps{constructor(){this.key="rgb",this.stringPrefix="rgb"}handleColor(t){const e=t.value.rgb??t.value;if(void 0!==e.r)return e}handleRangeColor(t){const e=t.value.rgb??t.value;if(void 0!==e.r)return{r:P(e.r),g:P(e.g),b:P(e.b)}}parseString(t){if(!t.startsWith(this.stringPrefix))return;const e=/rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*([\d.%]+)\s*)?\)/i.exec(t);return e?{a:e.length>4?H(e[5]):1,b:parseInt(e[3],10),g:parseInt(e[2],10),r:parseInt(e[1],10)}:void 0}}class fs{constructor(t){this.container=t,this.type="particles"}}const vs=function(){const t=new ps,e=new us;Ft(t),Ft(e);const i=new ds;return i.init(),i}();j()||(window.tsParticles=vs);class ms{static init(t){const e=new ms,i=t.selector;if(!i)throw new Error("No selector provided");const s=document.querySelector(i);if(!s)throw new Error("No element found for selector");return vs.set(i.replace(".","").replace("!",""),s,{fullScreen:{enable:!1},particles:{color:{value:t.color??"!000000"},links:{color:"random",distance:t.minDistance??120,enable:t.connectParticles??!1},move:{enable:!0,speed:t.speed??.5},number:{value:t.maxParticles??100},size:{value:{min:1,max:t.sizeVariations??3}}},responsive:t.responsive?.map((e=>({maxWidth:e.breakpoint,options:{particles:{color:{value:e.options?.color},links:{distance:e.options?.minDistance,enable:e.options?.connectParticles},number:{value:t.maxParticles},move:{enable:!0,speed:e.options?.speed},size:{value:e.options?.sizeVariations}}}})))}).then((t=>{e._container=t})),e}destroy(){const t=this._container;t&&t.destroy()}pauseAnimation(){const t=this._container;t&&t.pause()}resumeAnimation(){const t=this._container;t&&t.play()}}const ys=t=>{const{particlesJS:e,pJSDom:i}=(t=>{const e=(e,i)=>t.load(e,i);return e.load=(e,i,s)=>{t.loadJSON(e,i).then((t=>{t&&s(t)})).catch((()=>{s(void 0)}))},e.setOnClickHandler=e=>{t.setOnClickHandler(e)},{particlesJS:e,pJSDom:t.dom()}})(t);return window.particlesJS=e,window.pJSDom=i,window.Particles=ms,{particlesJS:e,pJSDom:i,Particles:ms}};function gs(t,e,i,s,o,n){!function(t,e){const i=t.options,s=i.move.path;if(!s.enable)return;if(t.lastPathTime<=t.pathDelay)return void(t.lastPathTime+=e.value);const o=t.pathGenerator?.generate(t,e);o&&t.velocity.addTo(o);s.clamp&&(t.velocity.x=k(t.velocity.x,-1,1),t.velocity.y=k(t.velocity.y,-1,1));t.lastPathTime-=t.pathDelay}(t,n);const a=t.gravity,r=a?.enable&&a.inverse?-1:1;o&&i&&(t.velocity.x+=o*n.factor/(60*i)),a?.enable&&i&&(t.velocity.y+=r*(a.acceleration*n.factor)/(60*i));const c=t.moveDecay;t.velocity.multTo(c);const l=t.velocity.mult(i);a?.enable&&s>0&&(!a.inverse&&l.y>=0&&l.y>=s||a.inverse&&l.y<=0&&l.y<=-s)&&(l.y=r*s,i&&(t.velocity.y=l.y/i));const h=t.options.zIndex,d=(1-t.zIndexFactor)**h.velocityRate;l.multTo(d);const{position:u}=t;u.addTo(l),e.vibrate&&(u.x+=Math.sin(u.x*Math.cos(u.y)),u.y+=Math.cos(u.y*Math.sin(u.x)))}class bs{constructor(){this._initSpin=t=>{const e=t.container,i=t.options.move.spin;if(!i.enable)return;const s=i.position??{x:50,y:50},o={x:s.x/100*e.canvas.size.width,y:s.y/100*e.canvas.size.height},n=D(t.getPosition(),o),a=P(i.acceleration);t.retina.spinAcceleration=a*e.retina.pixelRatio,t.spin={center:o,direction:t.velocity.x>=0?"clockwise":"counter-clockwise",angle:t.velocity.angle,radius:n,acceleration:t.retina.spinAcceleration}}}init(t){const e=t.options.move.gravity;t.gravity={enable:e.enable,acceleration:P(e.acceleration),inverse:e.inverse},this._initSpin(t)}isEnabled(t){return!t.destroyed&&t.options.move.enable}move(t,e){const i=t.options,s=i.move;if(!s.enable)return;const o=t.container,n=o.retina.pixelRatio,a=function(t){return t.slow.inRange?t.slow.factor:1}(t),r=(t.retina.moveSpeed??=P(s.speed)*n)*o.retina.reduceFactor,c=t.retina.moveDrift??=P(t.options.move.drift)*n,l=S(i.size.value)*n,h=r*(s.size?t.getRadius()/l:1)*a*(e.factor||1)/2,d=t.retina.maxSpeed??o.retina.maxSpeed;s.spin.enable?function(t,e){const i=t.container;if(!t.spin)return;const s={x:"clockwise"===t.spin.direction?Math.cos:Math.sin,y:"clockwise"===t.spin.direction?Math.sin:Math.cos};t.position.x=t.spin.center.x+t.spin.radius*s.x(t.spin.angle),t.position.y=t.spin.center.y+t.spin.radius*s.y(t.spin.angle),t.spin.radius+=t.spin.acceleration;const o=Math.max(i.canvas.size.width,i.canvas.size.height);t.spin.radius>o/2?(t.spin.radius=o/2,t.spin.acceleration*=-1):t.spin.radius<0&&(t.spin.radius=0,t.spin.acceleration*=-1),t.spin.angle+=e/100*(1-t.spin.radius/o)}(t,h):gs(t,s,h,d,c,e),function(t){const e=t.initialPosition,{dx:i,dy:s}=R(e,t.position),o=Math.abs(i),n=Math.abs(s),{maxDistance:a}=t.retina,r=a.horizontal,c=a.vertical;if(r||c)if((r&&o>=r||c&&n>=c)&&!t.misplaced)t.misplaced=!!r&&o>r||!!c&&n>c,r&&(t.velocity.x=t.velocity.y/2-t.velocity.x),c&&(t.velocity.y=t.velocity.x/2-t.velocity.y);else if((!r||oe.x&&s.x>0)&&(s.x*=-_()),c&&(i.ye.y&&s.y>0)&&(s.y*=-_())}}(t)}}class ws{draw(t,e,i){e.circleRange||(e.circleRange={min:0,max:2*Math.PI});const s=e.circleRange;t.arc(0,0,i,s.min,s.max,!1)}getSidesCount(){return 12}particleInit(t,e){const i=e.shapeData,s=i?.angle??{max:360,min:0};e.circleRange=_t(s)?{min:s.min*Math.PI/180,max:s.max*Math.PI/180}:{min:0,max:s*Math.PI/180}}}function xs(t,e,i,s,o){if(!e||!i.enable||(e.maxLoops??0)>0&&(e.loops??0)>(e.maxLoops??0))return;if(e.time||(e.time=0),(e.delayTime??0)>0&&e.time<(e.delayTime??0)&&(e.time+=t.value),(e.delayTime??0)>0&&e.time<(e.delayTime??0))return;const n=M(i.offset),a=(e.velocity??0)*t.factor+3.6*n,r=e.decay??1;o&&"increasing"!==e.status?(e.value-=a,e.value<0&&(e.loops||(e.loops=0),e.loops++,e.status="increasing",e.value+=e.value)):(e.value+=a,e.value>s&&(e.loops||(e.loops=0),e.loops++,o&&(e.status="decreasing",e.value-=e.value%s))),e.velocity&&1!==r&&(e.velocity*=r),e.value>s&&(e.value%=s)}class _s{constructor(t){this.container=t}init(t){const e=Wt(t.options.color,t.id,t.options.reduceDuplicates);e&&(t.color=ie(e,t.options.color.animation,this.container.retina.reduceFactor))}isEnabled(t){const{h:e,s:i,l:s}=t.options.color.animation,{color:o}=t;return!t.destroyed&&!t.spawning&&(void 0!==o?.h.value&&e.enable||void 0!==o?.s.value&&i.enable||void 0!==o?.l.value&&s.enable)}update(t,e){!function(t,e){const{h:i,s,l:o}=t.options.color.animation,{color:n}=t;if(!n)return;const{h:a,s:r,l:c}=n;a&&xs(e,a,i,360,!1),r&&xs(e,r,s,100,!0),c&&xs(e,c,o,100,!0)}(t,e)}}class ks{constructor(t){this.container=t}init(t){const e=t.options.opacity;t.opacity=ft(e,1);const i=e.animation;i.enable&&(t.opacity.velocity=P(i.speed)/100*this.container.retina.reduceFactor,i.sync||(t.opacity.velocity*=_()))}isEnabled(t){return!t.destroyed&&!t.spawning&&!!t.opacity&&t.opacity.enable&&((t.opacity.maxLoops??0)<=0||(t.opacity.maxLoops??0)>0&&(t.opacity.loops??0)<(t.opacity.maxLoops??0))}reset(t){t.opacity&&(t.opacity.time=0,t.opacity.loops=0)}update(t,e){this.isEnabled(t)&&function(t,e){const i=t.opacity;if(t.destroyed||!i?.enable||(i.maxLoops??0)>0&&(i.loops??0)>(i.maxLoops??0))return;const s=i.min,o=i.max,n=i.decay??1;if(i.time||(i.time=0),(i.delayTime??0)>0&&i.time<(i.delayTime??0)&&(i.time+=e.value),!((i.delayTime??0)>0&&i.time<(i.delayTime??0))){switch(i.status){case"increasing":i.value>=o?(i.status="decreasing",i.loops||(i.loops=0),i.loops++):i.value+=(i.velocity??0)*e.factor;break;case"decreasing":i.value<=s?(i.status="increasing",i.loops||(i.loops=0),i.loops++):i.value-=(i.velocity??0)*e.factor}i.velocity&&1!==i.decay&&(i.velocity*=n),function(t,e,i,s){switch(t.options.opacity.animation.destroy){case"max":e>=s&&t.destroy();break;case"min":e<=i&&t.destroy()}}(t,i.value,s,o),t.destroyed||(i.value=k(i.value,s,o))}}(t,e)}}class zs{constructor(t){this.container=t,this.modes=["bounce","bounce-vertical","bounce-horizontal","bounceVertical","bounceHorizontal","split"]}update(t,e,i,s){if(!this.modes.includes(s))return;const o=this.container;let n=!1;for(const[,s]of o.plugins)if(void 0!==s.particleBounce&&(n=s.particleBounce(t,i,e)),n)break;if(n)return;const a=t.getPosition(),r=t.offset,c=t.getRadius(),l=it(a,c),h=o.canvas.size;!function(t){if("bounce"!==t.outMode&&"bounce-horizontal"!==t.outMode&&"bounceHorizontal"!==t.outMode&&"split"!==t.outMode||"left"!==t.direction&&"right"!==t.direction)return;t.bounds.right<0&&"left"===t.direction?t.particle.position.x=t.size+t.offset.x:t.bounds.left>t.canvasSize.width&&"right"===t.direction&&(t.particle.position.x=t.canvasSize.width-t.size-t.offset.x);const e=t.particle.velocity.x;let i=!1;if("right"===t.direction&&t.bounds.right>=t.canvasSize.width&&e>0||"left"===t.direction&&t.bounds.left<=0&&e<0){const e=T(t.particle.options.bounce.horizontal);t.particle.velocity.x*=-e,i=!0}if(!i)return;const s=t.offset.x+t.size;t.bounds.right>=t.canvasSize.width&&"right"===t.direction?t.particle.position.x=t.canvasSize.width-s:t.bounds.left<=0&&"left"===t.direction&&(t.particle.position.x=s),"split"===t.outMode&&t.particle.destroy()}({particle:t,outMode:s,direction:e,bounds:l,canvasSize:h,offset:r,size:c}),function(t){if("bounce"!==t.outMode&&"bounce-vertical"!==t.outMode&&"bounceVertical"!==t.outMode&&"split"!==t.outMode||"bottom"!==t.direction&&"top"!==t.direction)return;t.bounds.bottom<0&&"top"===t.direction?t.particle.position.y=t.size+t.offset.y:t.bounds.top>t.canvasSize.height&&"bottom"===t.direction&&(t.particle.position.y=t.canvasSize.height-t.size-t.offset.y);const e=t.particle.velocity.y;let i=!1;if("bottom"===t.direction&&t.bounds.bottom>=t.canvasSize.height&&e>0||"top"===t.direction&&t.bounds.top<=0&&e<0){const e=T(t.particle.options.bounce.vertical);t.particle.velocity.y*=-e,i=!0}if(!i)return;const s=t.offset.y+t.size;t.bounds.bottom>=t.canvasSize.height&&"bottom"===t.direction?t.particle.position.y=t.canvasSize.height-s:t.bounds.top<=0&&"top"===t.direction&&(t.particle.position.y=s),"split"===t.outMode&&t.particle.destroy()}({particle:t,outMode:s,direction:e,bounds:l,canvasSize:h,offset:r,size:c})}}class Ms{constructor(t){this.container=t,this.modes=["destroy"]}update(t,e,i,s){if(!this.modes.includes(s))return;const o=this.container;switch(t.outType){case"normal":case"outside":if(tt(t.position,o.canvas.size,m.origin,t.getRadius(),e))return;break;case"inside":{const{dx:e,dy:i}=R(t.position,t.moveCenter),{x:s,y:o}=t.velocity;if(s<0&&e>t.moveCenter.radius||o<0&&i>t.moveCenter.radius||s>=0&&e<-t.moveCenter.radius||o>=0&&i<-t.moveCenter.radius)return;break}}o.particles.remove(t,void 0,!0)}}class Ps{constructor(t){this.container=t,this.modes=["none"]}update(t,e,i,s){if(!this.modes.includes(s))return;if(t.options.move.distance.horizontal&&("left"===e||"right"===e)||t.options.move.distance.vertical&&("top"===e||"bottom"===e))return;const o=t.options.move.gravity,n=this.container,a=n.canvas.size,r=t.getRadius();if(o.enable){const i=t.position;(!o.inverse&&i.y>a.height+r&&"bottom"===e||o.inverse&&i.y<-r&&"top"===e)&&n.particles.remove(t)}else{if(t.velocity.y>0&&t.position.y<=a.height+r||t.velocity.y<0&&t.position.y>=-r||t.velocity.x>0&&t.position.x<=a.width+r||t.velocity.x<0&&t.position.x>=-r)return;tt(t.position,n.canvas.size,m.origin,r,e)||n.particles.remove(t)}}}class Cs{constructor(t){this.container=t,this.modes=["out"]}update(t,e,i,s){if(!this.modes.includes(s))return;const o=this.container;switch(t.outType){case"inside":{const{x:e,y:i}=t.velocity,s=m.origin;s.length=t.moveCenter.radius,s.angle=t.velocity.angle+Math.PI,s.addTo(m.create(t.moveCenter));const{dx:n,dy:a}=R(t.position,s);if(e<=0&&n>=0||i<=0&&a>=0||e>=0&&n<=0||i>=0&&a<=0)return;t.position.x=Math.floor(M({min:0,max:o.canvas.size.width})),t.position.y=Math.floor(M({min:0,max:o.canvas.size.height}));const{dx:r,dy:c}=R(t.position,t.moveCenter);t.direction=Math.atan2(-c,-r),t.velocity.angle=t.direction;break}default:if(tt(t.position,o.canvas.size,m.origin,t.getRadius(),e))return;switch(t.outType){case"outside":{t.position.x=Math.floor(M({min:-t.moveCenter.radius,max:t.moveCenter.radius}))+t.moveCenter.x,t.position.y=Math.floor(M({min:-t.moveCenter.radius,max:t.moveCenter.radius}))+t.moveCenter.y;const{dx:e,dy:i}=R(t.position,t.moveCenter);t.moveCenter.radius&&(t.direction=Math.atan2(i,e),t.velocity.angle=t.direction);break}case"normal":{const i=t.options.move.warp,s=o.canvas.size,n={bottom:s.height+t.getRadius()+t.offset.y,left:-t.getRadius()-t.offset.x,right:s.width+t.getRadius()+t.offset.x,top:-t.getRadius()-t.offset.y},a=t.getRadius(),r=it(t.position,a);"right"===e&&r.left>s.width+t.offset.x?(t.position.x=n.left,t.initialPosition.x=t.position.x,i||(t.position.y=_()*s.height,t.initialPosition.y=t.position.y)):"left"===e&&r.right<-t.offset.x&&(t.position.x=n.right,t.initialPosition.x=t.position.x,i||(t.position.y=_()*s.height,t.initialPosition.y=t.position.y)),"bottom"===e&&r.top>s.height+t.offset.y?(i||(t.position.x=_()*s.width,t.initialPosition.x=t.position.x),t.position.y=n.top,t.initialPosition.y=t.position.y):"top"===e&&r.bottom<-t.offset.y&&(i||(t.position.x=_()*s.width,t.initialPosition.x=t.position.x),t.position.y=n.bottom,t.initialPosition.y=t.position.y);break}}}}}class Ss{constructor(t){this.container=t,this._updateOutMode=(t,e,i,s)=>{for(const o of this.updaters)o.update(t,s,e,i)},this.updaters=[new zs(t),new Ms(t),new Cs(t),new Ps(t)]}init(){}isEnabled(t){return!t.destroyed&&!t.spawning}update(t,e){const i=t.options.move.outModes;this._updateOutMode(t,e,i.bottom??i.default,"bottom"),this._updateOutMode(t,e,i.left??i.default,"left"),this._updateOutMode(t,e,i.right??i.default,"right"),this._updateOutMode(t,e,i.top??i.default,"top")}}class Os{init(t){const e=t.container,i=t.options.size.animation;i.enable&&(t.size.velocity=(t.retina.sizeAnimationSpeed??e.retina.sizeAnimationSpeed)/100*e.retina.reduceFactor,i.sync||(t.size.velocity*=_()))}isEnabled(t){return!t.destroyed&&!t.spawning&&t.size.enable&&((t.size.maxLoops??0)<=0||(t.size.maxLoops??0)>0&&(t.size.loops??0)<(t.size.maxLoops??0))}reset(t){t.size.loops=0}update(t,e){this.isEnabled(t)&&function(t,e){const i=t.size;if(t.destroyed||!i||!i.enable||(i.maxLoops??0)>0&&(i.loops??0)>(i.maxLoops??0))return;const s=(i.velocity??0)*e.factor,o=i.min,n=i.max,a=i.decay??1;if(i.time||(i.time=0),(i.delayTime??0)>0&&i.time<(i.delayTime??0)&&(i.time+=e.value),!((i.delayTime??0)>0&&i.time<(i.delayTime??0))){switch(i.status){case"increasing":i.value>=n?(i.status="decreasing",i.loops||(i.loops=0),i.loops++):i.value+=s;break;case"decreasing":i.value<=o?(i.status="increasing",i.loops||(i.loops=0),i.loops++):i.value-=s}i.velocity&&1!==a&&(i.velocity*=a),function(t,e,i,s){switch(t.options.size.animation.destroy){case"max":e>=s&&t.destroy();break;case"min":e<=i&&t.destroy()}}(t,i.value,o,n),t.destroyed||(i.value=k(i.value,o,n))}}(t,e)}}async function Ts(t,e=!0){await async function(t,e=!0){await t.addMover("base",(()=>new bs),e)}(t,!1),await async function(t,e=!0){await t.addShape("circle",new ws,e)}(t,!1),await async function(t,e=!0){await t.addParticleUpdater("color",(t=>new _s(t)),e)}(t,!1),await async function(t,e=!0){await t.addParticleUpdater("opacity",(t=>new ks(t)),e)}(t,!1),await async function(t,e=!0){await t.addParticleUpdater("outModes",(t=>new Ss(t)),e)}(t,!1),await async function(t,e=!0){await t.addParticleUpdater("size",(()=>new Os),e)}(t,!1),await t.refresh(e)}class Rs{constructor(){this.distance=200,this.duration=.4,this.easing="ease-out-quad",this.factor=1,this.maxSpeed=50,this.speed=1}load(t){t&&(void 0!==t.distance&&(this.distance=t.distance),void 0!==t.duration&&(this.duration=t.duration),void 0!==t.easing&&(this.easing=t.easing),void 0!==t.factor&&(this.factor=t.factor),void 0!==t.maxSpeed&&(this.maxSpeed=t.maxSpeed),void 0!==t.speed&&(this.speed=t.speed))}}class Ds extends li{constructor(t,e){super(e),this._clickAttract=()=>{const t=this.container;t.attract||(t.attract={particles:[]});const{attract:e}=t;if(e.finish||(e.count||(e.count=0),e.count++,e.count===t.particles.count&&(e.finish=!0)),e.clicking){const e=t.interactivity.mouse.clickPosition,i=t.retina.attractModeDistance;if(!i||i<0||!e)return;this._processAttract(e,i,new Ki(e.x,e.y,i))}else!1===e.clicking&&(e.particles=[])},this._hoverAttract=()=>{const t=this.container,e=t.interactivity.mouse.position,i=t.retina.attractModeDistance;!i||i<0||!e||this._processAttract(e,i,new Ki(e.x,e.y,i))},this._processAttract=(t,e,i)=>{const s=this.container,o=s.actualOptions.interactivity.modes.attract;if(!o)return;const n=s.particles.quadTree.query(i,(t=>this.isEnabled(t)));for(const i of n){const{dx:s,dy:n,distance:a}=R(i.position,t),r=o.speed*o.factor,c=k(w(o.easing)(1-a/e)*r,0,o.maxSpeed),l=m.create(0===a?r:s/a*c,0===a?r:n/a*c);i.position.subFrom(l)}},this._engine=t,e.attract||(e.attract={particles:[]}),this.handleClickMode=t=>{const i=this.container.actualOptions.interactivity.modes.attract;if(i&&"attract"===t){e.attract||(e.attract={particles:[]}),e.attract.clicking=!0,e.attract.count=0;for(const t of e.attract.particles)this.isEnabled(t)&&t.velocity.setTo(t.initialVelocity);e.attract.particles=[],e.attract.finish=!1,setTimeout((()=>{e.destroyed||(e.attract||(e.attract={particles:[]}),e.attract.clicking=!1)}),1e3*i.duration)}}}clear(){}init(){const t=this.container,e=t.actualOptions.interactivity.modes.attract;e&&(t.retina.attractModeDistance=e.distance*t.retina.pixelRatio)}async interact(){const t=this.container,e=t.actualOptions,i=t.interactivity.status===r,s=e.interactivity.events,o=s.onHover.enable,n=s.onHover.mode,a=s.onClick.enable,c=s.onClick.mode;i&&o&&J("attract",n)?this._hoverAttract():a&&J("attract",c)&&this._clickAttract()}isEnabled(t){const e=this.container,i=e.actualOptions,s=e.interactivity.mouse,o=(t?.interactivity??i.interactivity).events;if(!(s.position&&o.onHover.enable||s.clickPosition&&o.onClick.enable))return!1;const n=o.onHover.mode,a=o.onClick.mode;return J("attract",n)||J("attract",a)}loadModeOptions(t,...e){t.attract||(t.attract=new Rs);for(const i of e)t.attract.load(i?.attract)}reset(){}}class Es{constructor(){this.distance=200}load(t){t&&void 0!==t.distance&&(this.distance=t.distance)}}class Is extends li{constructor(t){super(t),this._processBounce=(t,e,i)=>{const s=this.container.particles.quadTree.query(i,(t=>this.isEnabled(t)));for(const o of s)i instanceof Ki?lt(ct(o),{position:t,radius:e,mass:e**2*Math.PI/2,velocity:m.origin,factor:m.origin}):i instanceof Qi&&ht(o,it(t,e))},this._processMouseBounce=()=>{const t=this.container,e=10*t.retina.pixelRatio,i=t.interactivity.mouse.position,s=t.retina.bounceModeDistance;!s||s<0||!i||this._processBounce(i,s,new Ki(i.x,i.y,s+e))},this._singleSelectorBounce=(t,e)=>{const i=this.container,s=document.querySelectorAll(t);s.length&&s.forEach((t=>{const s=t,o=i.retina.pixelRatio,n={x:(s.offsetLeft+s.offsetWidth/2)*o,y:(s.offsetTop+s.offsetHeight/2)*o},a=s.offsetWidth/2*o,r=10*o,c="circle"===e.type?new Ki(n.x,n.y,a+r):new Qi(s.offsetLeft*o-r,s.offsetTop*o-r,s.offsetWidth*o+2*r,s.offsetHeight*o+2*r);this._processBounce(n,a,c)}))}}clear(){}init(){const t=this.container,e=t.actualOptions.interactivity.modes.bounce;e&&(t.retina.bounceModeDistance=e.distance*t.retina.pixelRatio)}async interact(){const t=this.container,e=t.actualOptions.interactivity.events,i=t.interactivity.status===r,s=e.onHover.enable,o=e.onHover.mode,n=e.onDiv;i&&s&&J("bounce",o)?this._processMouseBounce():nt("bounce",n,((t,e)=>this._singleSelectorBounce(t,e)))}isEnabled(t){const e=this.container,i=e.actualOptions,s=e.interactivity.mouse,o=(t?.interactivity??i.interactivity).events,n=o.onDiv;return s.position&&o.onHover.enable&&J("bounce",o.onHover.mode)||ot("bounce",n)}loadModeOptions(t,...e){t.bounce||(t.bounce=new Es);for(const i of e)t.bounce.load(i?.bounce)}reset(){}}class Ls{constructor(){this.distance=200,this.duration=.4,this.mix=!1}load(t){if(t){if(void 0!==t.distance&&(this.distance=t.distance),void 0!==t.duration&&(this.duration=t.duration),void 0!==t.mix&&(this.mix=t.mix),void 0!==t.opacity&&(this.opacity=t.opacity),void 0!==t.color){const e=kt(this.color)?void 0:this.color;this.color=dt(t.color,(t=>zt.create(e,t)))}void 0!==t.size&&(this.size=t.size)}}}class As extends Ls{constructor(){super(),this.selectors=[]}get ids(){return dt(this.selectors,(t=>t.replace("#","")))}set ids(t){this.selectors=dt(t,(t=>`#${t}`))}load(t){super.load(t),t&&(void 0!==t.ids&&(this.ids=t.ids),void 0!==t.selectors&&(this.selectors=t.selectors))}}class Fs extends Ls{load(t){super.load(t),t&&(this.divs=dt(t.divs,(t=>{const e=new As;return e.load(t),e})))}}function Bs(t,e,i,s){if(e>=i){return k(t+(e-i)*s,t,e)}if(e{const t=this.container,e=t.actualOptions,i=t.interactivity.mouse.clickPosition,s=e.interactivity.modes.bubble;if(!s||!i)return;t.bubble||(t.bubble={});const o=t.retina.bubbleModeDistance;if(!o||o<0)return;const n=t.particles.quadTree.queryCircle(i,o,(t=>this.isEnabled(t))),{bubble:a}=t;for(const e of n){if(!a.clicking)continue;e.bubble.inRange=!a.durationEnd;const n=D(e.getPosition(),i),r=((new Date).getTime()-(t.interactivity.mouse.clickTime||0))/1e3;r>s.duration&&(a.durationEnd=!0),r>2*s.duration&&(a.clicking=!1,a.durationEnd=!1);const c={bubbleObj:{optValue:t.retina.bubbleModeSize,value:e.bubble.radius},particlesObj:{optValue:S(e.options.size.value)*t.retina.pixelRatio,value:e.size.value},type:"size"};this._process(e,n,r,c);const l={bubbleObj:{optValue:s.opacity,value:e.bubble.opacity},particlesObj:{optValue:S(e.options.opacity.value),value:e.opacity?.value??1},type:"opacity"};this._process(e,n,r,l),!a.durationEnd&&n<=o?this._hoverBubbleColor(e,n):delete e.bubble.color}},this._hoverBubble=()=>{const t=this.container,e=t.interactivity.mouse.position,i=t.retina.bubbleModeDistance;if(!i||i<0||void 0===e)return;const s=t.particles.quadTree.queryCircle(e,i,(t=>this.isEnabled(t)));for(const o of s){o.bubble.inRange=!0;const s=D(o.getPosition(),e),a=1-s/i;s<=i?a>=0&&t.interactivity.status===r&&(this._hoverBubbleSize(o,a),this._hoverBubbleOpacity(o,a),this._hoverBubbleColor(o,a)):this.reset(o),t.interactivity.status===n&&this.reset(o)}},this._hoverBubbleColor=(t,e,i)=>{const s=this.container.actualOptions,o=i??s.interactivity.modes.bubble;if(o){if(!t.bubble.finalColor){const e=o.color;if(!e)return;const i=ut(e);t.bubble.finalColor=Wt(i)}if(t.bubble.finalColor)if(o.mix){t.bubble.color=void 0;const i=t.getFillColor();t.bubble.color=i?$t(Qt(i,t.bubble.finalColor,1-e,e)):t.bubble.finalColor}else t.bubble.color=t.bubble.finalColor}},this._hoverBubbleOpacity=(t,e,i)=>{const s=this.container.actualOptions,o=i?.opacity??s.interactivity.modes.bubble?.opacity;if(!o)return;const n=t.options.opacity.value,a=Bs(t.opacity?.value??1,o,S(n),e);void 0!==a&&(t.bubble.opacity=a)},this._hoverBubbleSize=(t,e,i)=>{const s=this.container,o=i?.size?i.size*s.retina.pixelRatio:s.retina.bubbleModeSize;if(void 0===o)return;const n=S(t.options.size.value)*s.retina.pixelRatio,a=Bs(t.size.value,o,n,e);void 0!==a&&(t.bubble.radius=a)},this._process=(t,e,i,s)=>{const o=this.container,n=s.bubbleObj.optValue,a=o.actualOptions.interactivity.modes.bubble;if(!a||void 0===n)return;const r=a.duration,c=o.retina.bubbleModeDistance,l=s.particlesObj.optValue,h=s.bubbleObj.value,d=s.particlesObj.value||0,u=s.type;if(c&&!(c<0)&&n!==l)if(o.bubble||(o.bubble={}),o.bubble.durationEnd)h&&("size"===u&&delete t.bubble.radius,"opacity"===u&&delete t.bubble.opacity);else if(e<=c){if((h??d)!==n){const e=d-i*(d-n)/r;"size"===u&&(t.bubble.radius=e),"opacity"===u&&(t.bubble.opacity=e)}}else"size"===u&&delete t.bubble.radius,"opacity"===u&&delete t.bubble.opacity},this._singleSelectorHover=(t,e,i)=>{const s=this.container,o=document.querySelectorAll(e),n=s.actualOptions.interactivity.modes.bubble;n&&o.length&&o.forEach((e=>{const o=e,a=s.retina.pixelRatio,r={x:(o.offsetLeft+o.offsetWidth/2)*a,y:(o.offsetTop+o.offsetHeight/2)*a},c=o.offsetWidth/2*a,l="circle"===i.type?new Ki(r.x,r.y,c):new Qi(o.offsetLeft*a,o.offsetTop*a,o.offsetWidth*a,o.offsetHeight*a),h=s.particles.quadTree.query(l,(t=>this.isEnabled(t)));for(const e of h){if(!l.contains(e.getPosition()))continue;e.bubble.inRange=!0;const i=rt(n.divs,o);e.bubble.div&&e.bubble.div===o||(this.clear(e,t,!0),e.bubble.div=o),this._hoverBubbleSize(e,1,i),this._hoverBubbleOpacity(e,1,i),this._hoverBubbleColor(e,1,i)}}))},t.bubble||(t.bubble={}),this.handleClickMode=e=>{"bubble"===e&&(t.bubble||(t.bubble={}),t.bubble.clicking=!0)}}clear(t,e,i){t.bubble.inRange&&!i||(delete t.bubble.div,delete t.bubble.opacity,delete t.bubble.radius,delete t.bubble.color)}init(){const t=this.container,e=t.actualOptions.interactivity.modes.bubble;e&&(t.retina.bubbleModeDistance=e.distance*t.retina.pixelRatio,void 0!==e.size&&(t.retina.bubbleModeSize=e.size*t.retina.pixelRatio))}async interact(t){const e=this.container.actualOptions.interactivity.events,i=e.onHover,s=e.onClick,o=i.enable,n=i.mode,a=s.enable,r=s.mode,c=e.onDiv;o&&J("bubble",n)?this._hoverBubble():a&&J("bubble",r)?this._clickBubble():nt("bubble",c,((e,i)=>this._singleSelectorHover(t,e,i)))}isEnabled(t){const e=this.container,i=e.actualOptions,s=e.interactivity.mouse,o=(t?.interactivity??i.interactivity).events,{onClick:n,onDiv:a,onHover:r}=o,c=ot("bubble",a);return!!(c||r.enable&&s.position||n.enable&&s.clickPosition)&&(J("bubble",r.mode)||J("bubble",n.mode)||c)}loadModeOptions(t,...e){t.bubble||(t.bubble=new Fs);for(const i of e)t.bubble.load(i?.bubble)}reset(t){t.bubble.inRange=!1}}class Vs{constructor(){this.opacity=.5}load(t){t&&void 0!==t.opacity&&(this.opacity=t.opacity)}}class Hs{constructor(){this.distance=80,this.links=new Vs,this.radius=60}get lineLinked(){return this.links}set lineLinked(t){this.links=t}get line_linked(){return this.links}set line_linked(t){this.links=t}load(t){t&&(void 0!==t.distance&&(this.distance=t.distance),this.links.load(t.links??t.lineLinked??t.line_linked),void 0!==t.radius&&(this.radius=t.radius))}}function Us(t,e,i,s){const o=t.actualOptions.interactivity.modes.connect;if(o)return function(t,e,i,s){const o=Math.floor(i.getRadius()/e.getRadius()),n=e.getFillColor(),a=i.getFillColor();if(!n||!a)return;const r=e.getPosition(),c=i.getPosition(),l=Qt(n,a,e.getRadius(),i.getRadius()),h=t.createLinearGradient(r.x,r.y,c.x,c.y);return h.addColorStop(0,Zt(n,s)),h.addColorStop(o>1?1:o,Jt(l,s)),h.addColorStop(1,Zt(a,s)),h}(e,i,s,o.links.opacity)}function Ws(t,e,i){t.canvas.draw((s=>{const o=Us(t,s,e,i);if(!o)return;const n=e.getPosition(),a=i.getPosition();!function(t,e,i,s,o){vi(t,s,o),t.lineWidth=e,t.strokeStyle=i,t.stroke()}(s,e.retina.linksWidth??0,o,n,a)}))}class $s extends li{constructor(t){super(t)}clear(){}init(){const t=this.container,e=t.actualOptions.interactivity.modes.connect;e&&(t.retina.connectModeDistance=e.distance*t.retina.pixelRatio,t.retina.connectModeRadius=e.radius*t.retina.pixelRatio)}async interact(){const t=this.container;if(t.actualOptions.interactivity.events.onHover.enable&&"pointermove"===t.interactivity.status){const e=t.interactivity.mouse.position;if(!t.retina.connectModeDistance||t.retina.connectModeDistance<0||!t.retina.connectModeRadius||t.retina.connectModeRadius<0||!e)return;const i=Math.abs(t.retina.connectModeRadius),s=t.particles.quadTree.queryCircle(e,i,(t=>this.isEnabled(t)));let o=0;for(const e of s){const i=e.getPosition();for(const n of s.slice(o+1)){const s=n.getPosition(),o=Math.abs(t.retina.connectModeDistance),a=Math.abs(i.x-s.x),r=Math.abs(i.y-s.y);a{const n=e.getPosition();!function(t,e,i,s,o,n){vi(t,i,s),t.strokeStyle=Jt(o,n),t.lineWidth=e,t.stroke()}(t,e.retina.linksWidth??0,n,o,i,s)}))}class Xs extends li{constructor(t){super(t)}clear(){}init(){const t=this.container,e=t.actualOptions.interactivity.modes.grab;e&&(t.retina.grabModeDistance=e.distance*t.retina.pixelRatio)}async interact(){const t=this.container,e=t.actualOptions.interactivity;if(!e.modes.grab||!e.events.onHover.enable||t.interactivity.status!==r)return;const i=t.interactivity.mouse.position;if(!i)return;const s=t.retina.grabModeDistance;if(!s||s<0)return;const o=t.particles.quadTree.queryCircle(i,s,(t=>this.isEnabled(t)));for(const n of o){const o=D(n.getPosition(),i);if(o>s)continue;const a=e.modes.grab.links,r=a.opacity,c=r-o*r/s;if(c<=0)continue;const l=a.color??n.options.links?.color;if(!t.particles.grabLineColor&&l){const i=e.modes.grab.links;t.particles.grabLineColor=te(l,i.blink,i.consent)}const h=Kt(n,void 0,t.particles.grabLineColor);h&&Ns(t,n,h,c,i)}}isEnabled(t){const e=this.container,i=e.interactivity.mouse,s=(t?.interactivity??e.actualOptions.interactivity).events;return s.onHover.enable&&!!i.position&&J("grab",s.onHover.mode)}loadModeOptions(t,...e){t.grab||(t.grab=new js);for(const i of e)t.grab.load(i?.grab)}reset(){}}class Ys extends li{constructor(t){super(t),this.handleClickMode=t=>{if("pause"!==t)return;const e=this.container;e.getAnimationStatus()?e.pause():e.play()}}clear(){}init(){}async interact(){}isEnabled(){return!0}reset(){}}class Js{constructor(){this.default=!0,this.groups=[],this.quantity=4}get particles_nb(){return this.quantity}set particles_nb(t){this.quantity=O(t)}load(t){if(!t)return;void 0!==t.default&&(this.default=t.default),void 0!==t.groups&&(this.groups=t.groups.map((t=>t))),this.groups.length||(this.default=!0);const e=t.quantity??t.particles_nb;void 0!==e&&(this.quantity=O(e))}}class Zs extends li{constructor(t){super(t),this.handleClickMode=t=>{if("push"!==t)return;const e=this.container,i=e.actualOptions.interactivity.modes.push;if(!i)return;const s=P(i.quantity);if(s<=0)return;const o=K([void 0,...i.groups]),n=void 0!==o?e.actualOptions.particles.groups[o]:void 0;e.particles.push(s,e.interactivity.mouse,n,o)}}clear(){}init(){}async interact(){}isEnabled(){return!0}loadModeOptions(t,...e){t.push||(t.push=new Js);for(const i of e)t.push.load(i?.push)}reset(){}}class Qs{constructor(){this.quantity=2}get particles_nb(){return this.quantity}set particles_nb(t){this.quantity=O(t)}load(t){if(!t)return;const e=t.quantity??t.particles_nb;void 0!==e&&(this.quantity=O(e))}}class Ks extends li{constructor(t){super(t),this.handleClickMode=t=>{const e=this.container,i=e.actualOptions;if(!i.interactivity.modes.remove||"remove"!==t)return;const s=P(i.interactivity.modes.remove.quantity);e.particles.removeQuantity(s)}}clear(){}init(){}async interact(){}isEnabled(){return!0}loadModeOptions(t,...e){t.remove||(t.remove=new Qs);for(const i of e)t.remove.load(i?.remove)}reset(){}}class to{constructor(){this.distance=200,this.duration=.4,this.factor=100,this.speed=1,this.maxSpeed=50,this.easing="ease-out-quad"}load(t){t&&(void 0!==t.distance&&(this.distance=t.distance),void 0!==t.duration&&(this.duration=t.duration),void 0!==t.easing&&(this.easing=t.easing),void 0!==t.factor&&(this.factor=t.factor),void 0!==t.speed&&(this.speed=t.speed),void 0!==t.maxSpeed&&(this.maxSpeed=t.maxSpeed))}}class eo extends to{constructor(){super(),this.selectors=[]}get ids(){return dt(this.selectors,(t=>t.replace("#","")))}set ids(t){this.selectors=dt(t,(t=>`#${t}`))}load(t){super.load(t),t&&(void 0!==t.ids&&(this.ids=t.ids),void 0!==t.selectors&&(this.selectors=t.selectors))}}class io extends to{load(t){super.load(t),t&&(this.divs=dt(t.divs,(t=>{const e=new eo;return e.load(t),e})))}}class so extends li{constructor(t,e){super(e),this._clickRepulse=()=>{const t=this.container,e=t.actualOptions.interactivity.modes.repulse;if(!e)return;const i=t.repulse||{particles:[]};if(i.finish||(i.count||(i.count=0),i.count++,i.count===t.particles.count&&(i.finish=!0)),i.clicking){const s=t.retina.repulseModeDistance;if(!s||s<0)return;const o=Math.pow(s/6,3),n=t.interactivity.mouse.clickPosition;if(void 0===n)return;const a=new Ki(n.x,n.y,o),r=t.particles.quadTree.query(a,(t=>this.isEnabled(t)));for(const t of r){const{dx:s,dy:a,distance:r}=R(n,t.position),c=r**2,l=-o*e.speed/c;if(c<=o){i.particles.push(t);const e=m.create(s,a);e.length=l,t.velocity.setTo(e)}}}else if(!1===i.clicking){for(const t of i.particles)t.velocity.setTo(t.initialVelocity);i.particles=[]}},this._hoverRepulse=()=>{const t=this.container,e=t.interactivity.mouse.position,i=t.retina.repulseModeDistance;!i||i<0||!e||this._processRepulse(e,i,new Ki(e.x,e.y,i))},this._processRepulse=(t,e,i,s)=>{const o=this.container,n=o.particles.quadTree.query(i,(t=>this.isEnabled(t))),a=o.actualOptions.interactivity.modes.repulse;if(a)for(const i of n){const{dx:o,dy:n,distance:r}=R(i.position,t),c=(s?.speed??a.speed)*a.factor,l=k(w(a.easing)(1-r/e)*c,0,a.maxSpeed),h=m.create(0===r?c:o/r*l,0===r?c:n/r*l);i.position.addTo(h)}},this._singleSelectorRepulse=(t,e)=>{const i=this.container,s=i.actualOptions.interactivity.modes.repulse;if(!s)return;const o=document.querySelectorAll(t);o.length&&o.forEach((t=>{const o=t,n=i.retina.pixelRatio,a={x:(o.offsetLeft+o.offsetWidth/2)*n,y:(o.offsetTop+o.offsetHeight/2)*n},r=o.offsetWidth/2*n,c="circle"===e.type?new Ki(a.x,a.y,r):new Qi(o.offsetLeft*n,o.offsetTop*n,o.offsetWidth*n,o.offsetHeight*n),l=rt(s.divs,o);this._processRepulse(a,r,c,l)}))},this._engine=t,e.repulse||(e.repulse={particles:[]}),this.handleClickMode=t=>{const i=this.container.actualOptions.interactivity.modes.repulse;if(!i||"repulse"!==t)return;e.repulse||(e.repulse={particles:[]});const s=e.repulse;s.clicking=!0,s.count=0;for(const t of e.repulse.particles)this.isEnabled(t)&&t.velocity.setTo(t.initialVelocity);s.particles=[],s.finish=!1,setTimeout((()=>{e.destroyed||(s.clicking=!1)}),1e3*i.duration)}}clear(){}init(){const t=this.container,e=t.actualOptions.interactivity.modes.repulse;e&&(t.retina.repulseModeDistance=e.distance*t.retina.pixelRatio)}async interact(){const t=this.container,e=t.actualOptions,i=t.interactivity.status===r,s=e.interactivity.events,o=s.onHover,n=o.enable,a=o.mode,c=s.onClick,l=c.enable,h=c.mode,d=s.onDiv;i&&n&&J("repulse",a)?this._hoverRepulse():l&&J("repulse",h)?this._clickRepulse():nt("repulse",d,((t,e)=>this._singleSelectorRepulse(t,e)))}isEnabled(t){const e=this.container,i=e.actualOptions,s=e.interactivity.mouse,o=(t?.interactivity??i.interactivity).events,n=o.onDiv,a=o.onHover,r=o.onClick,c=ot("repulse",n);if(!(c||a.enable&&s.position||r.enable&&s.clickPosition))return!1;const l=a.mode,h=r.mode;return J("repulse",l)||J("repulse",h)||c}loadModeOptions(t,...e){t.repulse||(t.repulse=new io);for(const i of e)t.repulse.load(i?.repulse)}reset(){}}class oo{constructor(){this.factor=3,this.radius=200}load(t){t&&(void 0!==t.factor&&(this.factor=t.factor),void 0!==t.radius&&(this.radius=t.radius))}}class no extends li{constructor(t){super(t)}clear(t,e,i){t.slow.inRange&&!i||(t.slow.factor=1)}init(){const t=this.container,e=t.actualOptions.interactivity.modes.slow;e&&(t.retina.slowModeRadius=e.radius*t.retina.pixelRatio)}async interact(){}isEnabled(t){const e=this.container,i=e.interactivity.mouse,s=(t?.interactivity??e.actualOptions.interactivity).events;return s.onHover.enable&&!!i.position&&J("slow",s.onHover.mode)}loadModeOptions(t,...e){t.slow||(t.slow=new oo);for(const i of e)t.slow.load(i?.slow)}reset(t){t.slow.inRange=!1;const e=this.container,i=e.actualOptions,s=e.interactivity.mouse.position,o=e.retina.slowModeRadius,n=i.interactivity.modes.slow;if(!n||!o||o<0||!s)return;const a=D(s,t.getPosition()),r=a/o,c=n.factor,{slow:l}=t;a>o||(l.inRange=!0,l.factor=r/c)}}const ao=[0,4,2,1],ro=[8,8,4,2];class co{constructor(t){this.pos=0,this.data=new Uint8ClampedArray(t)}getString(t){const e=this.data.slice(this.pos,this.pos+t);return this.pos+=e.length,e.reduce(((t,e)=>t+String.fromCharCode(e)),"")}nextByte(){return this.data[this.pos++]}nextTwoBytes(){return this.pos+=2,this.data[this.pos-2]+(this.data[this.pos-1]<<8)}readSubBlocks(){let t="",e=0;do{e=this.data[this.pos++];for(let i=e;--i>=0;t+=String.fromCharCode(this.data[this.pos++]));}while(0!==e);return t}readSubBlocksBin(){let t=0,e=0;for(let i=0;0!==(t=this.data[this.pos+i]);i+=t+1)e+=t;const i=new Uint8Array(e);for(let e=0;0!==(t=this.data[this.pos++]);)for(let s=t;--s>=0;i[e++]=this.data[this.pos++]);return i}skipSubBlocks(){for(;0!==this.data[this.pos];this.pos+=this.data[this.pos]+1);this.pos++}}function lo(t,e){const i=[];for(let s=0;s>>3;const h=1<<1+(7&r);c&&(a.localColorTable=lo(t,h));const d=t=>{const{r:s,g:n,b:r}=(c?a.localColorTable:e.globalColorTable)[t];return{r:s,g:n,b:r,a:t===o(null)?i?~~((s+n+r)/3):0:255}},u=(()=>{try{return new ImageData(a.width,a.height,{colorSpace:"srgb"})}catch(t){if(t instanceof DOMException&&"IndexSizeError"===t.name)return null;throw t}})();if(null==u)throw new EvalError("GIF frame size is to large");const p=t.nextByte(),f=t.readSubBlocksBin(),v=1<{const i=t>>>3,s=7&t;return(f[i]+(f[i+1]<<8)+(f[i+2]<<16)&(1<>>s};if(l){for(let i=0,o=p+1,r=0,c=[[0]],l=0;l<4;l++){if(ao[l]=c.length?c.push(c[s].concat(c[s][0])):s!==v&&c.push(c[s].concat(c[i][0]));for(let s=0;s=a.height))break}n?.(t.pos/(t.data.length-1),s(!1)+1,u,{x:a.left,y:a.top},{width:e.width,height:e.height})}a.image=u,a.bitmap=await createImageBitmap(u)}else{for(let t=0,e=p+1,i=0,s=[[0]],o=-4;;){const n=t;if(t=m(i,e),i+=e,t===v){e=p+1,s.length=v+2;for(let t=0;t=s.length?s.push(s[n].concat(s[n][0])):n!==v&&s.push(s[n].concat(s[t][0]));for(let e=0;e=1<>>5,o.disposalMethod=(28&n)>>>2,o.userInputDelayFlag=2==(2&n);const a=1==(1&n);o.delayTime=10*t.nextTwoBytes();const r=t.nextByte();a&&s(r),t.pos++;break}case 255:{t.pos++;const i={identifier:t.getString(8),authenticationCode:t.getString(3),data:t.readSubBlocksBin()};e.applicationExtensions.push(i);break}case 254:e.comments.push([i(!1),t.readSubBlocks()]);break;case 1:if(0===e.globalColorTable.length)throw new EvalError("plain text extension without global color table");t.pos++,e.frames[i(!1)].plainTextData={left:t.nextTwoBytes(),top:t.nextTwoBytes(),width:t.nextTwoBytes(),height:t.nextTwoBytes(),charSize:{width:t.nextTwoBytes(),height:t.nextTwoBytes()},foregroundColor:t.nextByte(),backgroundColor:t.nextByte(),text:t.readSubBlocks()};break;default:t.skipSubBlocks()}}(t,e,s,o);break;default:throw new EvalError("undefined block found")}return!1}const uo=/(#(?:[0-9a-f]{2}){2,4}|(#[0-9a-f]{3})|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d.]+%?\))|currentcolor/gi;async function po(t){return new Promise((e=>{t.loading=!0;const i=new Image;t.element=i,i.addEventListener("load",(()=>{t.loading=!1,e()})),i.addEventListener("error",(()=>{t.element=void 0,t.error=!0,t.loading=!1,$().error(`${f} loading image: ${t.source}`),e()})),i.src=t.source}))}async function fo(t){if("gif"===t.type){t.loading=!0;try{t.gifData=await async function(t,e,i){i||(i=!1);const s=await fetch(t);if(!s.ok&&404===s.status)throw new EvalError("file not found");const o=await s.arrayBuffer(),n={width:0,height:0,totalTime:0,colorRes:0,pixelAspectRatio:0,frames:[],sortFlag:!1,globalColorTable:[],backgroundImage:new ImageData(1,1,{colorSpace:"srgb"}),comments:[],applicationExtensions:[]},a=new co(new Uint8ClampedArray(o));if("GIF89a"!==a.getString(6))throw new Error("not a supported GIF file");n.width=a.nextTwoBytes(),n.height=a.nextTwoBytes();const r=a.nextByte(),c=128==(128&r);n.colorRes=(112&r)>>>4,n.sortFlag=8==(8&r);const l=1<<1+(7&r),h=a.nextByte();n.pixelAspectRatio=a.nextByte(),0!==n.pixelAspectRatio&&(n.pixelAspectRatio=(n.pixelAspectRatio+15)/64),c&&(n.globalColorTable=lo(a,l));const d=(()=>{try{return new ImageData(n.width,n.height,{colorSpace:"srgb"})}catch(t){if(t instanceof DOMException&&"IndexSizeError"===t.name)return null;throw t}})();if(null==d)throw new Error("GIF frame size is to large");const{r:u,g:p,b:f}=n.globalColorTable[h];d.data.set(c?[u,p,f,255]:[0,0,0,0]);for(let t=4;t(t&&(m=!0),v),b=t=>(null!=t&&(y=t),y);try{do{m&&(n.frames.push({left:0,top:0,width:0,height:0,disposalMethod:0,image:new ImageData(1,1,{colorSpace:"srgb"}),plainTextData:null,userInputDelayFlag:!1,delayTime:0,sortFlag:!1,localColorTable:[],reserved:0,GCreserved:0}),v++,y=-1,m=!1)}while(!await ho(a,n,i,g,b,e));n.frames.length--;for(const t of n.frames){if(t.userInputDelayFlag&&0===t.delayTime){n.totalTime=1/0;break}n.totalTime+=t.delayTime}return n}catch(t){if(t instanceof EvalError)throw new Error(`error while parsing frame ${v} "${t.message}"`);throw t}}(t.source),t.gifLoopCount=function(t){for(const e of t.applicationExtensions)if(e.identifier+e.authenticationCode==="NETSCAPE2.0")return e.data[1]+(e.data[2]<<8);return NaN}(t.gifData)??0,0===t.gifLoopCount&&(t.gifLoopCount=1/0)}catch{t.error=!0}t.loading=!1}else await po(t)}async function vo(t){if("svg"!==t.type)return void await po(t);t.loading=!0;const e=await fetch(t.source);e.ok?t.svgData=await e.text():($().error(`${f} Image not found`),t.error=!0),t.loading=!1}function mo(t,e,i,s){const o=function(t,e,i){const{svgData:s}=t;if(!s)return"";const o=Zt(e,i);if(s.includes("fill"))return s.replace(uo,(()=>o));const n=s.indexOf(">");return`${s.substring(0,n)} fill="${o}"${s.substring(n)}`}(t,i,s.opacity?.value??1),n={color:i,gif:e.gif,data:{...t,svgData:o},loaded:!1,ratio:e.width/e.height,replaceColor:e.replaceColor??e.replace_color,source:e.src};return new Promise((e=>{const i=new Blob([o],{type:"image/svg+xml"}),s=URL||window.URL||window.webkitURL||window,a=s.createObjectURL(i),r=new Image;r.addEventListener("load",(()=>{n.loaded=!0,n.element=r,e(n),s.revokeObjectURL(a)})),r.addEventListener("error",(async()=>{s.revokeObjectURL(a);const i={...t,error:!1,loading:!0};await po(i),n.loaded=!0,n.element=i.element,e(n)})),r.src=a}))}class yo{constructor(t){this.loadImageShape=async t=>{if(!this._engine.loadImage)throw new Error(`${f} image shape not initialized`);await this._engine.loadImage({gif:t.gif,name:t.name,replaceColor:t.replaceColor??t.replace_color??!1,src:t.src})},this._engine=t}addImage(t){this._engine.images||(this._engine.images=[]),this._engine.images.push(t)}draw(t,e,i,s,o){const n=e.image,a=n?.element;if(n){if(t.globalAlpha=s,n.gif&&n.gifData){const s=new OffscreenCanvas(n.gifData.width,n.gifData.height),a=s.getContext("2d");if(!a)throw new Error("could not create offscreen canvas context");a.imageSmoothingQuality="low",a.imageSmoothingEnabled=!1,a.clearRect(0,0,s.width,s.height),void 0===e.gifLoopCount&&(e.gifLoopCount=n.gifLoopCount??0);let r=e.gifFrame??0;const c={x:.5*-n.gifData.width,y:.5*-n.gifData.height},l=n.gifData.frames[r];if(void 0===e.gifTime&&(e.gifTime=0),!l.bitmap)return;switch(t.scale(i/n.gifData.width,i/n.gifData.height),l.disposalMethod){case 4:case 5:case 6:case 7:case 0:a.drawImage(l.bitmap,l.left,l.top),t.drawImage(s,c.x,c.y),a.clearRect(0,0,s.width,s.height);break;case 1:a.drawImage(l.bitmap,l.left,l.top),t.drawImage(s,c.x,c.y);break;case 2:a.drawImage(l.bitmap,l.left,l.top),t.drawImage(s,c.x,c.y),a.clearRect(0,0,s.width,s.height),0===n.gifData.globalColorTable.length?a.putImageData(n.gifData.frames[0].image,c.x+l.left,c.y+l.top):a.putImageData(n.gifData.backgroundImage,c.x,c.y);break;case 3:{const e=a.getImageData(0,0,s.width,s.height);a.drawImage(l.bitmap,l.left,l.top),t.drawImage(s,c.x,c.y),a.clearRect(0,0,s.width,s.height),a.putImageData(e,0,0)}}if(e.gifTime+=o.value,e.gifTime>l.delayTime){if(e.gifTime-=l.delayTime,++r>=n.gifData.frames.length){if(--e.gifLoopCount<=0)return;r=0,a.clearRect(0,0,s.width,s.height)}e.gifFrame=r}t.scale(n.gifData.width/i,n.gifData.height/i)}else if(a){const e=n.ratio,s={x:-i,y:-i};t.drawImage(a,s.x,s.y,2*i,2*i/e)}t.globalAlpha=1}}getSidesCount(){return 12}async init(t){const e=t.actualOptions;if(e.preload&&this._engine.loadImage)for(const t of e.preload)await this._engine.loadImage(t)}loadShape(t){if("image"!==t.shape&&"images"!==t.shape)return;this._engine.images||(this._engine.images=[]);const e=t.shapeData;this._engine.images.find((t=>t.name===e.name||t.source===e.src))||this.loadImageShape(e).then((()=>{this.loadShape(t)}))}particleInit(t,e){if("image"!==e.shape&&"images"!==e.shape)return;this._engine.images||(this._engine.images=[]);const i=this._engine.images,s=e.shapeData,o=e.getFillColor(),n=i.find((t=>t.name===s.name||t.source===s.src));if(!n)return;const a=s.replaceColor??s.replace_color??n.replaceColor;n.loading?setTimeout((()=>{this.particleInit(t,e)})):(async()=>{let t;t=n.svgData&&o?await mo(n,s,o,e):{color:o,data:n,element:n.element,gif:n.gif,gifData:n.gifData,gifLoopCount:n.gifLoopCount,loaded:!0,ratio:s.width&&s.height?s.width/s.height:n.ratio??1,replaceColor:a,source:s.src},t.ratio||(t.ratio=1);const i={image:t,fill:s.fill??e.fill,close:s.close??e.close};e.image=i.image,e.fill=i.fill,e.close=i.close})()}}class go{constructor(){this.src="",this.gif=!1}load(t){t&&(void 0!==t.gif&&(this.gif=t.gif),void 0!==t.height&&(this.height=t.height),void 0!==t.name&&(this.name=t.name),void 0!==t.replaceColor&&(this.replaceColor=t.replaceColor),void 0!==t.src&&(this.src=t.src),void 0!==t.width&&(this.width=t.width))}}class bo{constructor(t){this.id="imagePreloader",this._engine=t}getPlugin(){return{}}loadOptions(t,e){if(!e||!e.preload)return;t.preload||(t.preload=[]);const i=t.preload;for(const t of e.preload){const e=i.find((e=>e.name===t.name||e.src===t.src));if(e)e.load(t);else{const e=new go;e.load(t),i.push(e)}}}needsPlugin(){return!0}}async function wo(t,e=!0){!function(t){t.loadImage||(t.loadImage=async e=>{if(!e.name&&!e.src)throw new Error(`${f} no image source provided`);if(t.images||(t.images=[]),!t.images.find((t=>t.name===e.name||t.source===e.src)))try{const i={gif:e.gif??!1,name:e.name??e.src,source:e.src,type:e.src.substring(e.src.length-3),error:!1,loading:!0,replaceColor:e.replaceColor,ratio:e.width&&e.height?e.width/e.height:void 0};t.images.push(i);const s=e.gif?fo:e.replaceColor?vo:po;await s(i)}catch{throw new Error(`${f} ${e.name??e.src} not found`)}})}(t);const i=new bo(t);await t.addPlugin(i,e),await t.addShape(["image","images"],new yo(t),e)}class xo extends St{constructor(){super(),this.sync=!1}load(t){t&&(super.load(t),void 0!==t.sync&&(this.sync=t.sync))}}class _o extends St{constructor(){super(),this.random.minimumValue=1e-4,this.sync=!1}load(t){t&&(super.load(t),void 0!==t.sync&&(this.sync=t.sync))}}class ko{constructor(){this.count=0,this.delay=new xo,this.duration=new _o}load(t){t&&(void 0!==t.count&&(this.count=t.count),this.delay.load(t.delay),this.duration.load(t.duration))}}class zo{constructor(t){this.container=t}init(t){const e=this.container,i=t.options.life;i&&(t.life={delay:e.retina.reduceFactor?P(i.delay.value)*(i.delay.sync?1:_())/e.retina.reduceFactor*1e3:0,delayTime:0,duration:e.retina.reduceFactor?P(i.duration.value)*(i.duration.sync?1:_())/e.retina.reduceFactor*1e3:0,time:0,count:i.count},t.life.duration<=0&&(t.life.duration=-1),t.life.count<=0&&(t.life.count=-1),t.life&&(t.spawning=t.life.delay>0))}isEnabled(t){return!t.destroyed}loadOptions(t,...e){t.life||(t.life=new ko);for(const i of e)t.life.load(i?.life)}update(t,e){if(!this.isEnabled(t)||!t.life)return;const i=t.life;let s=!1;if(t.spawning){if(i.delayTime+=e.value,!(i.delayTime>=t.life.delay))return;s=!0,t.spawning=!1,i.delayTime=0,i.time=0}if(-1===i.duration)return;if(t.spawning)return;if(s?i.time=0:i.time+=e.value,i.time0&&t.life.count--,0===t.life.count)return void t.destroy();const o=this.container.canvas.size,n=O(0,o.width),a=O(0,o.width);t.position.x=M(n),t.position.y=M(a),t.spawning=!0,i.delayTime=0,i.time=0,t.reset();const r=t.options.life;r&&(i.delay=1e3*P(r.delay.value),i.duration=1e3*P(r.duration.value))}}class Mo{draw(t,e,i){const s=e.shapeData;t.moveTo(-i/2,0),t.lineTo(i/2,0),t.lineCap=s?.cap??"butt"}getSidesCount(){return 1}}class Po{init(){}isEnabled(t){return!j()&&!t.destroyed&&t.container.actualOptions.interactivity.events.onHover.parallax.enable}move(t){const e=t.container,i=e.actualOptions.interactivity.events.onHover.parallax;if(j()||!i.enable)return;const s=i.force,o=e.interactivity.mouse.position;if(!o)return;const n=e.canvas.size,a=n.width/2,r=n.height/2,c=i.smooth,l=t.getRadius()/s,h=(o.x-a)*l,d=(o.y-r)*l,{offset:u}=t;u.x+=(h-u.x)/c,u.y+=(d-u.y)/c}}class Co extends fs{constructor(t){super(t)}clear(){}init(){}async interact(t){const e=this.container,i=t.retina.attractDistance??e.retina.attractDistance,s=t.getPosition(),o=e.particles.quadTree.queryCircle(s,i);for(const e of o){if(t===e||!e.options.move.attract.enable||e.destroyed||e.spawning)continue;const i=e.getPosition(),{dx:o,dy:n}=R(s,i),a=t.options.move.attract.rotate,r=o/(1e3*a.x),c=n/(1e3*a.y),l=e.size.value/t.size.value,h=1/l;t.velocity.x-=r*l,t.velocity.y-=c*l,e.velocity.x+=r*h,e.velocity.y+=c*h}}isEnabled(t){return t.options.move.attract.enable}reset(){}}function So(t,e,i,s,o,n){const a=k(t.options.collisions.absorb.speed*o.factor/10,0,s);t.size.value+=a/2,i.size.value-=a,s<=n&&(i.size.value=0,i.destroy())}const Oo=t=>{void 0===t.collisionMaxSpeed&&(t.collisionMaxSpeed=P(t.options.collisions.maxSpeed)),t.velocity.length>t.collisionMaxSpeed&&(t.velocity.length=t.collisionMaxSpeed)};function To(t,e){lt(ct(t),ct(e)),Oo(t),Oo(e)}function Ro(t,e,i,s){switch(t.options.collisions.mode){case"absorb":!function(t,e,i,s){const o=t.getRadius(),n=e.getRadius();void 0===o&&void 0!==n?t.destroy():void 0!==o&&void 0===n?e.destroy():void 0!==o&&void 0!==n&&(o>=n?So(t,0,e,n,i,s):So(e,0,t,o,i,s))}(t,e,i,s);break;case"bounce":To(t,e);break;case"destroy":!function(t,e){t.unbreakable||e.unbreakable||To(t,e),void 0===t.getRadius()&&void 0!==e.getRadius()?t.destroy():void 0!==t.getRadius()&&void 0===e.getRadius()?e.destroy():void 0!==t.getRadius()&&void 0!==e.getRadius()&&(t.getRadius()>=e.getRadius()?e:t).destroy()}(t,e)}}class Do extends fs{constructor(t){super(t)}clear(){}init(){}async interact(t,e){if(t.destroyed||t.spawning)return;const i=this.container,s=t.getPosition(),o=t.getRadius(),n=i.particles.quadTree.queryCircle(s,2*o);for(const a of n){if(t===a||!a.options.collisions.enable||t.options.collisions.mode!==a.options.collisions.mode||a.destroyed||a.spawning)continue;const n=a.getPosition(),r=a.getRadius();if(Math.abs(Math.round(s.z)-Math.round(n.z))>o+r)continue;D(s,n)>o+r||Ro(t,a,e,i.retina.pixelRatio)}}isEnabled(t){return t.options.collisions.enable}reset(){}}class Eo extends Ki{constructor(t,e,i,s){super(t,e,i),this.canvasSize=s,this.canvasSize={...s}}contains(t){const{width:e,height:i}=this.canvasSize,{x:s,y:o}=t;return super.contains(t)||super.contains({x:s-e,y:o})||super.contains({x:s-e,y:o-i})||super.contains({x:s,y:o-i})}intersects(t){if(super.intersects(t))return!0;const e=t,i=t,s={x:t.position.x-this.canvasSize.width,y:t.position.y-this.canvasSize.height};if(void 0!==i.radius){const t=new Ki(s.x,s.y,2*i.radius);return super.intersects(t)}if(void 0!==e.size){const t=new Qi(s.x,s.y,2*e.size.width,2*e.size.height);return super.intersects(t)}return!1}}class Io{constructor(){this.blur=5,this.color=new zt,this.color.value="#000",this.enable=!1}load(t){t&&(void 0!==t.blur&&(this.blur=t.blur),this.color=zt.create(this.color,t.color),void 0!==t.enable&&(this.enable=t.enable))}}class Lo{constructor(){this.enable=!1,this.frequency=1}load(t){t&&(void 0!==t.color&&(this.color=zt.create(this.color,t.color)),void 0!==t.enable&&(this.enable=t.enable),void 0!==t.frequency&&(this.frequency=t.frequency),void 0!==t.opacity&&(this.opacity=t.opacity))}}class Ao{constructor(){this.blink=!1,this.color=new zt,this.color.value="#fff",this.consent=!1,this.distance=100,this.enable=!1,this.frequency=1,this.opacity=1,this.shadow=new Io,this.triangles=new Lo,this.width=1,this.warp=!1}load(t){t&&(void 0!==t.id&&(this.id=t.id),void 0!==t.blink&&(this.blink=t.blink),this.color=zt.create(this.color,t.color),void 0!==t.consent&&(this.consent=t.consent),void 0!==t.distance&&(this.distance=t.distance),void 0!==t.enable&&(this.enable=t.enable),void 0!==t.frequency&&(this.frequency=t.frequency),void 0!==t.opacity&&(this.opacity=t.opacity),this.shadow.load(t.shadow),this.triangles.load(t.triangles),void 0!==t.width&&(this.width=t.width),void 0!==t.warp&&(this.warp=t.warp))}}function Fo(t,e,i,s,o){const{dx:n,dy:a,distance:r}=R(t,e);if(!o||r<=i)return r;const c={x:Math.abs(n),y:Math.abs(a)},l=Math.min(c.x,s.width-c.x),h=Math.min(c.y,s.height-c.y);return Math.sqrt(l**2+h**2)}class Bo extends fs{constructor(t){super(t),this._setColor=t=>{if(!t.options.links)return;const e=this.linkContainer,i=t.options.links;let s=void 0===i.id?e.particles.linksColor:e.particles.linksColors.get(i.id);if(s)return;s=te(i.color,i.blink,i.consent),void 0===i.id?e.particles.linksColor=s:e.particles.linksColors.set(i.id,s)},this.linkContainer=t}clear(){}init(){this.linkContainer.particles.linksColor=void 0,this.linkContainer.particles.linksColors=new Map}async interact(t){if(!t.options.links)return;t.links=[];const e=t.getPosition(),i=this.container,s=i.canvas.size;if(e.x<0||e.y<0||e.x>s.width||e.y>s.height)return;const o=t.options.links,n=o.opacity,a=t.retina.linksDistance??0,r=o.warp,c=r?new Eo(e.x,e.y,a,s):new Ki(e.x,e.y,a),l=i.particles.quadTree.query(c);for(const i of l){const c=i.options.links;if(t===i||!c?.enable||o.id!==c.id||i.spawning||i.destroyed||!i.links||t.links.some((t=>t.destination===i))||i.links.some((e=>e.destination===t)))continue;const l=i.getPosition();if(l.x<0||l.y<0||l.x>s.width||l.y>s.height)continue;const h=Fo(e,l,a,s,r&&c.warp);if(h>a)continue;const d=(1-h/a)*n;this._setColor(t),t.links.push({destination:i,opacity:d})}}isEnabled(t){return!!t.options.links?.enable}loadParticlesOptions(t,...e){t.links||(t.links=new Ao);for(const i of e)t.links.load(i?.links??i?.lineLinked??i?.line_linked)}reset(){}}function qo(t,e){const i=((s=t.map((t=>t.id))).sort(((t,e)=>t-e)),s.join("_"));var s;let o=e.get(i);return void 0===o&&(o=_(),e.set(i,o)),o}class Vo{constructor(t){this.container=t,this._drawLinkLine=(t,e)=>{const i=t.options.links;if(!i?.enable)return;const s=this.container,o=s.actualOptions,n=e.destination,a=t.getPosition(),r=n.getPosition();let c=e.opacity;s.canvas.draw((e=>{let l;const h=t.options.twinkle?.lines;if(h?.enable){const t=h.frequency,e=Vt(h.color);_(){const s=t.options.links;if(!s?.enable)return;const o=s.triangles;if(!o.enable)return;const n=this.container,a=n.actualOptions,r=e.destination,c=i.destination,l=o.opacity??(e.opacity+i.opacity)/2;l<=0||n.canvas.draw((e=>{const i=t.getPosition(),h=r.getPosition(),d=c.getPosition(),u=t.retina.linksDistance??0;if(D(i,h)>u||D(d,h)>u||D(d,i)>u)return;let p=Vt(o.color);if(!p){const e=void 0!==s.id?n.particles.linksColors.get(s.id):n.particles.linksColor;p=Kt(t,r,e)}p&&function(t){const{context:e,pos1:i,pos2:s,pos3:o,backgroundMask:n,colorTriangle:a,opacityTriangle:r}=t;mi(e,i,s,o),n.enable&&(e.globalCompositeOperation=n.composite),e.fillStyle=Jt(a,r),e.fill()}({context:e,pos1:i,pos2:h,pos3:d,backgroundMask:a.backgroundMask,colorTriangle:p,opacityTriangle:l})}))},this._drawTriangles=(t,e,i,s)=>{const o=i.destination;if(!t.links?.triangles.enable||!o.options.links?.triangles.enable)return;const n=o.links?.filter((t=>{const e=this._getLinkFrequency(o,t.destination);return o.options.links&&e<=o.options.links.frequency&&s.findIndex((e=>e.destination===t.destination))>=0}));if(n?.length)for(const s of n){const n=s.destination;this._getTriangleFrequency(e,o,n)>t.links.triangles.frequency||this._drawLinkTriangle(e,i,s)}},this._getLinkFrequency=(t,e)=>qo([t,e],this._freqs.links),this._getTriangleFrequency=(t,e,i)=>qo([t,e,i],this._freqs.triangles),this._freqs={links:new Map,triangles:new Map}}drawParticle(t,e){const{links:i,options:s}=e;if(!i||i.length<=0)return;const o=i.filter((t=>s.links&&this._getLinkFrequency(e,t.destination)<=s.links.frequency));for(const t of o)this._drawTriangles(s,e,t,o),t.opacity>0&&(e.retina.linksWidth??0)>0&&this._drawLinkLine(e,t)}async init(){this._freqs.links=new Map,this._freqs.triangles=new Map}particleCreated(t){if(t.links=[],!t.options.links)return;const e=this.container.retina.pixelRatio,{retina:i}=t,{distance:s,width:o}=t.options.links;i.linksDistance=s*e,i.linksWidth=o*e}particleDestroyed(t){t.links=[]}}class Ho{constructor(){this.id="links"}getPlugin(t){return new Vo(t)}loadOptions(){}needsPlugin(){return!0}}async function Uo(t,e=!0){await async function(t,e=!0){await t.addInteractor("particlesLinks",(t=>new Bo(t)),e)}(t,e),await async function(t,e=!0){const i=new Ho;await t.addPlugin(i,e)}(t,e)}class Wo{draw(t,e,i){const s=this.getCenter(e,i),o=this.getSidesData(e,i),n=o.count.numerator*o.count.denominator,a=o.count.numerator/o.count.denominator,r=180*(a-2)/a,c=Math.PI-Math.PI*r/180;if(t){t.beginPath(),t.translate(s.x,s.y),t.moveTo(0,0);for(let e=0;e0?"counter-clockwise":"clockwise"}switch(i){case"counter-clockwise":case"counterClockwise":t.rotate.status="decreasing";break;case"clockwise":t.rotate.status="increasing"}const s=e.animation;s.enable&&(t.rotate.decay=1-P(s.decay),t.rotate.velocity=P(s.speed)/360*this.container.retina.reduceFactor,s.sync||(t.rotate.velocity*=_())),t.rotation=t.rotate.value}isEnabled(t){const e=t.options.rotate;return!!e&&(!t.destroyed&&!t.spawning&&e.animation.enable&&!e.path)}loadOptions(t,...e){t.rotate||(t.rotate=new Xo);for(const i of e)t.rotate.load(i?.rotate)}update(t,e){this.isEnabled(t)&&(!function(t,e){const i=t.rotate,s=t.options.rotate;if(!i||!s)return;const o=s.animation,n=(i.velocity??0)*e.factor,a=2*Math.PI,r=i.decay??1;o.enable&&("increasing"===i.status?(i.value+=n,i.value>a&&(i.value-=a)):(i.value-=n,i.value<0&&(i.value+=a)),i.velocity&&1!==r&&(i.velocity*=r))}(t,e),t.rotation=t.rotate?.value??0)}}const Jo=Math.sqrt(2);class Zo{draw(t,e,i){const s=i/Jo,o=2*s;t.rect(-s,-s,o,o)}getSidesCount(){return 4}}class Qo{draw(t,e,i){const s=e.sides,o=e.starInset??2;t.moveTo(0,0-i);for(let e=0;e0&&(e.loops??0)>(e.maxLoops??0))return;if(e.time||(e.time=0),(e.delayTime??0)>0&&e.time<(e.delayTime??0)&&(e.time+=t.value),(e.delayTime??0)>0&&e.time<(e.delayTime??0))return;const n=M(i.offset),a=(e.velocity??0)*t.factor+3.6*n,r=e.decay??1;o&&"increasing"!==e.status?(e.value-=a,e.value<0&&(e.loops||(e.loops=0),e.loops++,e.status="increasing",e.value+=e.value)):(e.value+=a,e.value>s&&(e.loops||(e.loops=0),e.loops++,o&&(e.status="decreasing",e.value-=e.value%s))),e.velocity&&1!==r&&(e.velocity*=r),e.value>s&&(e.value%=s)}class tn{constructor(t){this.container=t}init(t){const e=this.container,i=t.options,s=ut(i.stroke,t.id,i.reduceDuplicates);t.strokeWidth=P(s.width)*e.retina.pixelRatio,t.strokeOpacity=P(s.opacity??1),t.strokeAnimation=s.color?.animation;const o=Wt(s.color)??t.getFillColor();o&&(t.strokeColor=ie(o,t.strokeAnimation,e.retina.reduceFactor))}isEnabled(t){const e=t.strokeAnimation,{strokeColor:i}=t;return!t.destroyed&&!t.spawning&&!!e&&(void 0!==i?.h.value&&i.h.enable||void 0!==i?.s.value&&i.s.enable||void 0!==i?.l.value&&i.l.enable)}update(t,e){this.isEnabled(t)&&function(t,e){if(!t.strokeColor||!t.strokeAnimation)return;const{h:i,s,l:o}=t.strokeColor,{h:n,s:a,l:r}=t.strokeAnimation;i&&Ko(e,i,n,360,!1),s&&Ko(e,s,a,100,!0),o&&Ko(e,o,r,100,!0)}(t,e)}}const en=["text","character","char"];class sn{draw(t,e,i,s){const o=e.shapeData;if(void 0===o)return;const n=o.value;if(void 0===n)return;void 0===e.text&&(e.text=ut(n,e.randomIndexData));const a=e.text,r=o.style??"",c=o.weight??"400",l=2*Math.round(i),h=o.font??"Verdana",d=e.fill,u=a.length*i/2;t.font=`${r} ${c} ${l}px "${h}"`;const p={x:-u,y:i/2};t.globalAlpha=s,d?t.fillText(a,p.x,p.y):t.strokeText(a,p.x,p.y),t.globalAlpha=1}getSidesCount(){return 12}async init(t){const e=t.actualOptions;if(en.find((t=>J(t,e.particles.shape.type)))){const t=en.map((t=>e.particles.shape.options[t])).find((t=>!!t)),i=[];dt(t,(t=>{i.push(Z(t.font,t.weight))})),await Promise.all(i)}}particleInit(t,e){if(!e.shape||!en.includes(e.shape))return;const i=e.shapeData;if(void 0===i)return;const s=i.value;void 0!==s&&(e.text=ut(s,e.randomIndexData))}}async function on(t,e=!0){ys(t),await async function(t,e=!0){await t.addMover("parallax",(()=>new Po),e)}(t,!1),await async function(t,e=!0){await t.addInteractor("externalAttract",(e=>new Ds(t,e)),e)}(t,!1),await async function(t,e=!0){await t.addInteractor("externalBounce",(t=>new Is(t)),e)}(t,!1),await async function(t,e=!0){await t.addInteractor("externalBubble",(t=>new qs(t)),e)}(t,!1),await async function(t,e=!0){await t.addInteractor("externalConnect",(t=>new $s(t)),e)}(t,!1),await async function(t,e=!0){await t.addInteractor("externalGrab",(t=>new Xs(t)),e)}(t,!1),await async function(t,e=!0){await t.addInteractor("externalPause",(t=>new Ys(t)),e)}(t,!1),await async function(t,e=!0){await t.addInteractor("externalPush",(t=>new Zs(t)),e)}(t,!1),await async function(t,e=!0){await t.addInteractor("externalRemove",(t=>new Ks(t)),e)}(t,!1),await async function(t,e=!0){await t.addInteractor("externalRepulse",(e=>new so(t,e)),e)}(t,!1),await async function(t,e=!0){await t.addInteractor("externalSlow",(t=>new no(t)),e)}(t,!1),await async function(t,e=!0){await t.addInteractor("particlesAttract",(t=>new Co(t)),e)}(t,!1),await async function(t,e=!0){await t.addInteractor("particlesCollisions",(t=>new Do(t)),e)}(t,!1),await Uo(t,!1),await async function(){b("ease-in-quad",(t=>t**2)),b("ease-out-quad",(t=>1-(1-t)**2)),b("ease-in-out-quad",(t=>t<.5?2*t**2:1-(-2*t+2)**2/2))}(),await wo(t,!1),await async function(t,e=!0){await t.addShape("line",new Mo,e)}(t,!1),await jo(t,!1),await async function(t,e=!0){await t.addShape(["edge","square"],new Zo,e)}(t,!1),await async function(t,e=!0){await t.addShape("star",new Qo,e)}(t,!1),await async function(t,e=!0){await t.addShape(en,new sn,e)}(t,!1),await async function(t,e=!0){await t.addParticleUpdater("life",(t=>new zo(t)),e)}(t,!1),await async function(t,e=!0){await t.addParticleUpdater("rotate",(t=>new Yo(t)),e)}(t,!1),await async function(t,e=!0){await t.addParticleUpdater("strokeColor",(t=>new tn(t)),e)}(t,!1),await Ts(t,e)}class nn{constructor(){this.enable=!1,this.speed=0,this.decay=0,this.sync=!1}load(t){t&&(void 0!==t.enable&&(this.enable=t.enable),void 0!==t.speed&&(this.speed=O(t.speed)),void 0!==t.decay&&(this.decay=O(t.decay)),void 0!==t.sync&&(this.sync=t.sync))}}class an extends St{constructor(){super(),this.animation=new nn,this.direction="clockwise",this.enable=!1,this.value=0}load(t){super.load(t),t&&(this.animation.load(t.animation),void 0!==t.direction&&(this.direction=t.direction),void 0!==t.enable&&(this.enable=t.enable))}}class rn{constructor(t){this.container=t}getTransformValues(t){const e=t.tilt?.enable&&t.tilt;return{b:e?Math.cos(e.value)*e.cosDirection:void 0,c:e?Math.sin(e.value)*e.sinDirection:void 0}}init(t){const e=t.options.tilt;if(!e)return;t.tilt={enable:e.enable,value:P(e.value)*Math.PI/180,sinDirection:_()>=.5?1:-1,cosDirection:_()>=.5?1:-1};let i=e.direction;if("random"===i){i=Math.floor(2*_())>0?"counter-clockwise":"clockwise"}switch(i){case"counter-clockwise":case"counterClockwise":t.tilt.status="decreasing";break;case"clockwise":t.tilt.status="increasing"}const s=t.options.tilt?.animation;s?.enable&&(t.tilt.decay=1-P(s.decay),t.tilt.velocity=P(s.speed)/360*this.container.retina.reduceFactor,s.sync||(t.tilt.velocity*=_()))}isEnabled(t){const e=t.options.tilt?.animation;return!t.destroyed&&!t.spawning&&!!e?.enable}loadOptions(t,...e){t.tilt||(t.tilt=new an);for(const i of e)t.tilt.load(i?.tilt)}update(t,e){this.isEnabled(t)&&function(t,e){if(!t.tilt||!t.options.tilt)return;const i=t.options.tilt.animation,s=(t.tilt.velocity??0)*e.factor,o=2*Math.PI,n=t.tilt.decay??1;i.enable&&("increasing"===t.tilt.status?(t.tilt.value+=s,t.tilt.value>o&&(t.tilt.value-=o)):(t.tilt.value-=s,t.tilt.value<0&&(t.tilt.value+=o)),t.tilt.velocity&&1!==n&&(t.tilt.velocity*=n))}(t,e)}}class cn{constructor(){this.enable=!1,this.frequency=.05,this.opacity=1}load(t){t&&(void 0!==t.color&&(this.color=zt.create(this.color,t.color)),void 0!==t.enable&&(this.enable=t.enable),void 0!==t.frequency&&(this.frequency=t.frequency),void 0!==t.opacity&&(this.opacity=O(t.opacity)))}}class ln{constructor(){this.lines=new cn,this.particles=new cn}load(t){t&&(this.lines.load(t.lines),this.particles.load(t.particles))}}class hn{getColorStyles(t,e,i,s){const o=t.options.twinkle;if(!o)return{};const n=o.particles,a=n.enable&&_()a&&(s.angle-=a),r.x+=n*Math.cos(s.angle),r.y+=n*Math.abs(Math.sin(s.angle))}(t,e)}}async function fn(t,e=!0){await async function(t,e=!0){await t.addParticleUpdater("destroy",(e=>new Je(t,e)),e)}(t,!1),await async function(t,e=!0){await t.addParticleUpdater("roll",(()=>new fi),e)}(t,!1),await async function(t,e=!0){await t.addParticleUpdater("tilt",(t=>new rn(t)),e)}(t,!1),await async function(t,e=!0){await t.addParticleUpdater("twinkle",(()=>new hn),e)}(t,!1),await async function(t,e=!0){await t.addParticleUpdater("wobble",(t=>new pn(t)),e)}(t,!1),await async function(t,e=!0){await t.addInteractor("externalTrail",(t=>new di(t)),e)}(t,!1),await async function(t,e=!0){await t.addPlugin(new ae,e)}(t,!1),await async function(t,e=!0){t.emitterShapeManager||(t.emitterShapeManager=new ni(t)),t.addEmitterShape||(t.addEmitterShape=(e,i)=>{t.emitterShapeManager?.addShape(e,i)});const i=new ci(t);await t.addPlugin(i,e),t.addEmitterShape("circle",new Ze),t.addEmitterShape("square",new ri)}(t,!1),await on(t,e)}return fn(vs),e})())); \ No newline at end of file diff --git a/src/ui/static/js/utils/file.manager.js b/src/ui/static/js/utils/file.manager.js index 4ada55857..c01fa3501 100644 --- a/src/ui/static/js/utils/file.manager.js +++ b/src/ui/static/js/utils/file.manager.js @@ -1,656 +1,656 @@ -class FolderNav { - constructor(prefix) { - this.prefix = prefix; - this.breadContainer = document.querySelector( - `[data-${this.prefix}-breadcrumb]` - ); - this.container = document.querySelector(`[data-${this.prefix}-container]`); - this.listContainer = document.querySelector( - `[data-${this.prefix}-folders]` - ); - this.els = document.querySelectorAll(`div[data-${this.prefix}-element]`); - this.files = document.querySelectorAll( - `div[data-${this.prefix}-element][data-_type='file']` - ); - this.addFileEl = document.querySelector(`[data-${this.prefix}-add-file]`); - this.addFolderEl = document.querySelector( - `[data-${this.prefix}-add-folder]` - ); - this.initSorted(); - this.initNav(); - } - - //sorted elements to get folders first - initSorted() { - this.files.forEach((file) => { - this.listContainer.append(file); - }); - } - - initNav() { - this.container.addEventListener("click", (e) => { - //GO ON NESTED FOLDER - try { - if (e.target.closest("div").getAttribute("data-_type") === "folder") { - //avoid logic on action btn click - const folder = e.target.closest("div[data-_type='folder']"); - this.updatedNested(folder); - } - } catch (err) {} - //BREACRUMB ITEM - try { - if ( - e.target - .closest("li") - .hasAttribute(`data-${this.prefix}-breadcrumb-item`) && - !e.target.closest("li").hasAttribute(`data-${this.prefix}-back`) && - e.target.closest("li").nextSibling !== null - ) { - const breadItem = e.target.closest("li"); - this.updateBread(breadItem); - } - } catch (err) {} - //BREADCRUMB BACK LOGIC - try { - if ( - e.target.closest("li").hasAttribute(`data-${this.prefix}-back`) && - +this.breadContainer.lastElementChild.getAttribute("data-level") !== 0 - ) { - //back is like clicking on last prev element - const prevItem = - this.breadContainer.lastElementChild.previousElementSibling; - this.updateBread(prevItem); - } - } catch (err) {} - }); - } - - //go to nested folder element - updatedNested(folder) { - const [folderPath, folderLvl, folderTxt] = this.getElAtt(folder); - //hidden all - this.hiddenConfEls(); - //show every files in folder - this.showCurrentFolderEls(folderPath, +folderLvl); - //update breadcrumb - this.appendBreadItem(folderPath, folderLvl, folderTxt); - //update actions - this.updateActions(folder); - } - - //update clicked bread and check for allow add conf - updateBread(item) { - const [prevPath, prevLvl, prevTxt] = this.getElAtt(item); - this.hiddenConfEls(); - //show every files in folder - this.showCurrentFolderEls(prevPath, +prevLvl); - //remove useless bread - this.removeBreadElByLvl(+prevLvl); - const folder = document.querySelector( - `div[data-${this.prefix}-element][data-path='${item.getAttribute( - "data-path" - )}']` - ); - this.updateActions(folder); - } - - //check if file/folder can be created on folder - updateActions(folder) { - //by default - this.hideAddConf(); - //check if folder allow add file/folder - const isAddFile = folder.getAttribute("data-can-create-file"); - const isAddFolder = folder.getAttribute("data-can-create-folder"); - isAddFile === "True" ? this.addFileEl.classList.remove("hidden") : ""; - isAddFolder === "True" ? this.addFolderEl.classList.remove("hidden") : ""; - } - - hideAddConf() { - this.addFileEl.classList.add("hidden"); - this.addFolderEl.classList.add("hidden"); - } - - showCurrentFolderEls(path, lvl) { - const nestedEl = document.querySelectorAll( - `div[data-path^="${path}/"][data-level="${+lvl + 1}"]` - ); - for (let i = 0; i < nestedEl.length; i++) { - const el = nestedEl[i]; - el.setAttribute("data-current-el", ""); - el.classList.remove("hidden"); - } - } - - //remove the bread items with a higher level than - //the clicked bread item - removeBreadElByLvl(lvl) { - const breadcrumbItem = this.breadContainer.querySelectorAll( - `[data-${this.prefix}-breadcrumb-item]` - ); - breadcrumbItem.forEach((item) => { - if ( - item.hasAttribute("data-level") && - +item.getAttribute("data-level") > lvl - ) - item.remove(); - }); - } - - //retrieve path, level and text - getElAtt(el) { - const newPath = el.getAttribute("data-path"); - const newLvl = el.getAttribute("data-level"); - const newTxt = el.getAttribute("data-name"); - return [newPath, newLvl, newTxt]; - } - - //hidden all folders - hiddenConfEls() { - this.els = document.querySelectorAll(`div[data-${this.prefix}-element]`); - this.els.forEach((el) => { - el.classList.add("hidden"); - el.removeAttribute("data-current-el"); - }); - } - - //add a bread item as last child with needed info - appendBreadItem(path, level, name) { - //create item el - const itemEl = document.createElement("li"); - itemEl.className = "leading-normal text-sm"; - //set item atts - const itemAtt = [ - ["data-path", path], - [`data-${this.prefix}-breadcrumb-item`, ""], - ["data-level", level], - ["data-name", name], - ]; - for (let i = 0; i < itemAtt.length; i++) { - itemEl.setAttribute(`${itemAtt[i][0]}`, `${itemAtt[i][1]}`); - } - //create nested btn el - const nestedBtnEl = document.createElement("button"); - nestedBtnEl.className = - "ml-2 dark:text-gray-500 text-gray-600 after:float-right after:pl-2 after:text-gray-600 dark:after:text-gray-500 after:content-['/']"; - itemEl.appendChild(nestedBtnEl); - nestedBtnEl.setAttribute("type", "button"); - nestedBtnEl.textContent = name; - this.breadContainer.appendChild(itemEl); - } -} - -class FolderDropdown { - constructor(prefix) { - this.prefix = prefix; - this.container = document.querySelector(`[data-${this.prefix}-container]`); - this.dropEls = document.querySelectorAll( - `[data-${this.prefix}-action-dropdown]` - ); - this.init(); - } - - init() { - let prevActionBtn = ""; //compare with curr to hide or not prev - this.container.addEventListener("click", (e) => { - //remove when none click - try { - if ( - !e.target - .closest("div") - .hasAttribute(`data-${this.prefix}-action-button`) - ) { - this.hideDropEls(); - } - } catch (err) {} - //show dropdown actions for folders - try { - if ( - e.target - .closest("div") - .hasAttribute(`data-${this.prefix}-action-button`) - ) { - const dropEl = e.target - .closest(`div[data-${this.prefix}-element]`) - .querySelector(`[data-${this.prefix}-action-dropdown]`); - //avoid multiple dropdown - if (prevActionBtn === "") prevActionBtn = dropEl; - if (prevActionBtn !== dropEl) this.hideDropEls(); - this.toggleDrop(dropEl); - prevActionBtn = dropEl; - } - } catch (err) {} - //hide dropdown clicking an action - try { - if ( - e.target - .closest("button") - .hasAttribute(`data-${this.prefix}-action-dropdown-btn`) - ) { - const att = e.target - .closest("button") - .getAttribute(`data-${this.prefix}-action-dropdown-btn`); - const dropEl = document.querySelector( - `[data-${this.prefix}-action-dropdown="${att}"]` - ); - this.hideDrop(dropEl); - } - } catch (err) {} - }); - } - - //UTILS - - toggleDrop(dropEl) { - dropEl.classList.toggle("hidden"); - dropEl.classList.toggle("flex"); - } - - hideDrop(dropEl) { - dropEl.classList.add("hidden"); - dropEl.classList.remove("flex"); - } - - hideDropEls() { - this.dropEls.forEach((drop) => { - this.hideDrop(drop); - }); - } -} - -class FolderEditor { - constructor() { - this.editor = ace.edit("editor"); - this.darkMode = document.querySelector("[data-dark-toggle]"); - this.initEditor(); - this.listenDarkToggle(); - } - - initEditor() { - //editor options - this.editor.setShowPrintMargin(false); - this.setDarkMode(); - } - - //listen to dark toggle button to change theme - listenDarkToggle() { - this.darkMode.addEventListener("click", (e) => { - this.darkMode.checked - ? this.changeDarkMode(true) - : this.changeDarkMode(false); - }); - } - - setDarkMode() { - document.querySelector("html").className.includes("dark") - ? this.editor.setTheme("ace/theme/dracula") - : this.editor.setTheme("ace/theme/dawn"); - } - - //change theme according to mode - changeDarkMode(bool) { - bool - ? this.editor.setTheme("ace/theme/dracula") - : this.editor.setTheme("ace/theme/dawn"); - } - - readOnlyBool(bool) { - this.editor.setReadOnly(bool); - } -} - -class FolderModal { - constructor(prefix) { - this.prefix = prefix; - //container - this.container = document.querySelector(`[data-${this.prefix}-container]`); - //add service/file elements - this.breadContainer = document.querySelector( - `[data-${this.prefix}-breadcrumb]` - ); - this.addConfContainer = document.querySelector( - `[data-${this.prefix}-add-container]` - ); - //modal DOM elements - this.form = document.querySelector(`[data-${this.prefix}-modal-form]`); - this.modalEl = document.querySelector(`[data-${this.prefix}-modal]`); - this.modalTitle = this.modalEl.querySelector( - `[data-${this.prefix}-modal-title]` - ); - this.modalPath = this.modalEl.querySelector( - `[data-${this.prefix}-modal-path]` - ); - this.modalEditor = this.modalEl.querySelector( - `[data-${this.prefix}-modal-editor]` - ); - this.modalPathPrev = this.modalPath.querySelector( - `p[data-${this.prefix}-modal-path-prefix]` - ); - this.modalPathName = this.modalPath.querySelector("input"); - this.modalPathSuffix = this.modalPath.querySelector( - `p[data-${this.prefix}-modal-path-suffix]` - ); - - this.modalSubmit = this.modalEl.querySelector( - `[data-${this.prefix}-modal-submit]` - ); - //hidden input for backend - this.modalInpPath = this.modalEl.querySelector("#path"); - this.modalInpOperation = this.modalEl.querySelector("#operation"); - this.modalInpType = this.modalEl.querySelector("#_type"); - this.modalInpOldName = this.modalEl.querySelector("#old_name"); - this.modalTxtarea = this.modalEl.querySelector("#content"); - //HANDLERS - //modal and values logic after clicking add file/folder button - this.initAddConfig(); - //modal and values logic after clicking actions buttons - this.initActionToModal(); - //modal element logic - this.initModal(); - //modal submit check and filter before submit - this.initForm(); - } - - //HANDLERS - initAddConfig() { - this.addConfContainer.addEventListener("click", (e) => { - //add folder - try { - if ( - e.target.closest("li").hasAttribute(`data-${this.prefix}-add-folder`) - ) { - this.setModal( - "new", - this.getPathFromBread(), - "folder", - "", - "", - this.getLevelFromBread() - ); - } - } catch (err) {} - //add file - try { - if ( - e.target.closest("li").hasAttribute(`data-${this.prefix}-add-file`) - ) { - this.setModal( - "new", - this.getPathFromBread(), - "file", - "", - "", - this.getLevelFromBread() - ); - } - } catch (err) {} - }); - } - - initActionToModal() { - this.container.addEventListener("click", (e) => { - //click on file logic - try { - if (e.target.closest("div").getAttribute("data-_type") == "file") { - const btnEl = e.target.closest("div").querySelector("button[value]"); - const [action, path, type, content, name, level] = - this.getInfoFromActionBtn(btnEl); - this.setModal(action, path, type, content, name, level); - this.showModal(); - } - } catch (err) {} - //set data of folder and show modal unless it's download btn - try { - if ( - e.target - .closest("button") - .hasAttribute(`data-${this.prefix}-action-dropdown-btn`) && - e.target.closest("button").getAttribute("value") !== "download" - ) { - const btnEl = e.target.closest("button"); - const [action, path, type, content, name, level] = - this.getInfoFromActionBtn(btnEl); - this.setModal(action, path, type, content, name, level); - this.showModal(); - } - } catch (err) {} - //download btn logic - try { - if ( - e.target - .closest("button") - .hasAttribute(`data-${this.prefix}-action-dropdown-btn`) && - e.target.closest("button").getAttribute("value") === "download" - ) { - const btnEl = e.target.closest("button"); - const [action, path, type, content, name, level] = - this.getInfoFromActionBtn(btnEl); - this.download(name, content); - } - } catch (err) {} - }); - } - - initModal() { - this.modalEl.addEventListener("click", (e) => { - //close modal logic - try { - if ( - e.target - .closest("button") - .hasAttribute(`data-${this.prefix}-modal-close`) - ) { - this.closeModal(); - } - } catch (err) {} - }); - } - - download(filename, text) { - var element = document.createElement("a"); - element.setAttribute( - "href", - "data:text/plain;charset=utf-8," + encodeURIComponent(text) - ); - element.setAttribute("download", filename); - - element.style.display = "none"; - document.body.appendChild(element); - - element.click(); - - document.body.removeChild(element); - } - - initForm() { - this.form.addEventListener("submit", (e) => { - e.preventDefault(); - //submit nothing case - if (this.modalInpOperation.value === "view") { - return this.closeModal(); - } - //else set data to input and request - this.setDataForRequest(); - }); - } - - //get data of custom inputs and set it on submit input - setDataForRequest() { - //set path to input - if (this.modalInpType === "folder") { - const prevPath = this.modalPathPrev.textContent; - const name = this.modalPathName.value; - this.modalInpPath.value = `${prevPath}${name}`; - } - //set textarea value from editor - const newTextarea = ace.edit("editor").getValue(); - this.modalTxtarea.value = newTextarea; - this.form.submit(); - } - - //for add file/folder btn - //get path of last bread element - getPathFromBread() { - const path = this.breadContainer.lastElementChild.getAttribute("data-path"); - return `${path}/`; - } - - getLevelFromBread() { - const level = - this.breadContainer.lastElementChild.getAttribute("data-level"); - return level; - } - //set all needed data from btn action and folder info - setModal(action, path, type, content, name, level) { - //title - this.modalTitle.textContent = `${action} ${type}`; - this.setInpt(action, path, type, name); - this.setEditor(type, content); - this.setSubmitTxt(action); - this.setPath(action, path, type, name, level); - this.setDisabled(action); - this.showModal(); - } - - //for hidden input to send on backend - //on form submit, check for update values before send request - setInpt(action, path, type, name) { - this.modalInpPath.value = - type === "file" && this.prefix === "configs" - ? path.replace(".conf", "") - : path; - this.modalInpType.value = type; - this.modalInpOperation.value = action; - this.modalInpOldName.value = - type === "file" && this.prefix === "configs" - ? name.replace(".conf", "") - : name; - } - - //path is empty if new one, else show current name - setPath(action, path, type) { - let [prevPath, name] = this.separatePath(path); - //remove conf if file type - this.modalPathSuffix.textContent = - type === "file" && this.prefix === "configs" ? ".conf" : ""; - name = - type === "file" && this.prefix === "configs" - ? name.replace(".conf", "") - : name; - - if (action === "new") { - this.modalPathPrev.textContent = `${path}`; - this.modalPathName.value = ``; - } - - if (action !== "new") { - this.modalPathPrev.textContent = `${prevPath}`; - this.modalPathName.value = `${name}`; - } - } - - //separate name and previous of path for DOM elements - separatePath(path) { - const splitPath = path.split("/"); - const nme = splitPath[splitPath.length - 1]; - const prev = path.replace(nme, ""); - return [prev, nme]; - } - - //disabled for view and delete actions - setDisabled(action) { - action === "view" || action === "delete" || action === "download" - ? this.disabledDOMInpt(true) - : this.disabledDOMInpt(false); - } - - //submit text depending action - setSubmitTxt(action) { - this.delSubmitBtnType(); - if (action === "new") { - this.modalSubmit.textContent = "add"; - this.setSubmitBtnType("valid-btn"); - return; - } - if (action === "view") { - this.modalSubmit.textContent = "ok"; - this.setSubmitBtnType("valid-btn"); - return; - } - if (action === "edit") { - this.setSubmitBtnType("edit-btn"); - this.modalSubmit.textContent = "edit"; - return; - } - - if (action === "delete") { - this.setSubmitBtnType("delete-btn"); - this.modalSubmit.textContent = "delete"; - return; - } - if (action === "download") { - this.setSubmitBtnType("info-btn"); - this.modalSubmit.textContent = "download"; - return; - } - } - - setSubmitBtnType(btnType) { - this.modalSubmit.classList.add(btnType); - } - - delSubmitBtnType() { - this.modalSubmit.classList.remove( - "delete-btn", - "valid-btn", - "edit-btn", - "info-btn" - ); - } - - //show only if type file and display text - setEditor(type, content) { - //SHOW LOGIC - if (type === "folder") this.modalEditor.classList.add("hidden"); - - if (type === "file") this.modalEditor.classList.remove("hidden"); - - ace.edit("editor").setValue(content); - } - - //get all needed info when clicking on action btn - getInfoFromActionBtn(btnEl) { - const action = btnEl.getAttribute("value"); - const name = btnEl.getAttribute(`data-${this.prefix}-action-dropdown-btn`); - const folder = btnEl.closest(`[data-${this.prefix}-element]`); - const level = folder.getAttribute("data-level"); - const path = folder.getAttribute("data-path"); - const type = folder.getAttribute("data-_type"); - let content; - try { - content = folder - .querySelector(`[data-${this.prefix}-content]`) - .getAttribute("data-value"); - } catch (err) { - content = ""; - } - return [action, path, type, content, name, level]; - } - - //UTILS - disabledDOMInpt(bool) { - this.modalPathName.disabled = bool; - ace.edit("editor").setReadOnly(bool); - } - - closeModal() { - this.modalEl.classList.add("hidden"); - this.modalEl.classList.remove("flex"); - } - - showModal() { - this.modalEl.classList.add("flex"); - this.modalEl.classList.remove("hidden"); - } -} - -export { FolderNav, FolderModal, FolderEditor, FolderDropdown }; +class FolderNav { + constructor(prefix) { + this.prefix = prefix; + this.breadContainer = document.querySelector( + `[data-${this.prefix}-breadcrumb]`, + ); + this.container = document.querySelector(`[data-${this.prefix}-container]`); + this.listContainer = document.querySelector( + `[data-${this.prefix}-folders]`, + ); + this.els = document.querySelectorAll(`div[data-${this.prefix}-element]`); + this.files = document.querySelectorAll( + `div[data-${this.prefix}-element][data-_type='file']`, + ); + this.addFileEl = document.querySelector(`[data-${this.prefix}-add-file]`); + this.addFolderEl = document.querySelector( + `[data-${this.prefix}-add-folder]`, + ); + this.initSorted(); + this.initNav(); + } + + //sorted elements to get folders first + initSorted() { + this.files.forEach((file) => { + this.listContainer.append(file); + }); + } + + initNav() { + this.container.addEventListener("click", (e) => { + //GO ON NESTED FOLDER + try { + if (e.target.closest("div").getAttribute("data-_type") === "folder") { + //avoid logic on action btn click + const folder = e.target.closest("div[data-_type='folder']"); + this.updatedNested(folder); + } + } catch (err) {} + //BREACRUMB ITEM + try { + if ( + e.target + .closest("li") + .hasAttribute(`data-${this.prefix}-breadcrumb-item`) && + !e.target.closest("li").hasAttribute(`data-${this.prefix}-back`) && + e.target.closest("li").nextSibling !== null + ) { + const breadItem = e.target.closest("li"); + this.updateBread(breadItem); + } + } catch (err) {} + //BREADCRUMB BACK LOGIC + try { + if ( + e.target.closest("li").hasAttribute(`data-${this.prefix}-back`) && + +this.breadContainer.lastElementChild.getAttribute("data-level") !== 0 + ) { + //back is like clicking on last prev element + const prevItem = + this.breadContainer.lastElementChild.previousElementSibling; + this.updateBread(prevItem); + } + } catch (err) {} + }); + } + + //go to nested folder element + updatedNested(folder) { + const [folderPath, folderLvl, folderTxt] = this.getElAtt(folder); + //hidden all + this.hiddenConfEls(); + //show every files in folder + this.showCurrentFolderEls(folderPath, +folderLvl); + //update breadcrumb + this.appendBreadItem(folderPath, folderLvl, folderTxt); + //update actions + this.updateActions(folder); + } + + //update clicked bread and check for allow add conf + updateBread(item) { + const [prevPath, prevLvl, prevTxt] = this.getElAtt(item); + this.hiddenConfEls(); + //show every files in folder + this.showCurrentFolderEls(prevPath, +prevLvl); + //remove useless bread + this.removeBreadElByLvl(+prevLvl); + const folder = document.querySelector( + `div[data-${this.prefix}-element][data-path='${item.getAttribute( + "data-path", + )}']`, + ); + this.updateActions(folder); + } + + //check if file/folder can be created on folder + updateActions(folder) { + //by default + this.hideAddConf(); + //check if folder allow add file/folder + const isAddFile = folder.getAttribute("data-can-create-file"); + const isAddFolder = folder.getAttribute("data-can-create-folder"); + isAddFile === "True" ? this.addFileEl.classList.remove("hidden") : ""; + isAddFolder === "True" ? this.addFolderEl.classList.remove("hidden") : ""; + } + + hideAddConf() { + this.addFileEl.classList.add("hidden"); + this.addFolderEl.classList.add("hidden"); + } + + showCurrentFolderEls(path, lvl) { + const nestedEl = document.querySelectorAll( + `div[data-path^="${path}/"][data-level="${+lvl + 1}"]`, + ); + for (let i = 0; i < nestedEl.length; i++) { + const el = nestedEl[i]; + el.setAttribute("data-current-el", ""); + el.classList.remove("hidden"); + } + } + + //remove the bread items with a higher level than + //the clicked bread item + removeBreadElByLvl(lvl) { + const breadcrumbItem = this.breadContainer.querySelectorAll( + `[data-${this.prefix}-breadcrumb-item]`, + ); + breadcrumbItem.forEach((item) => { + if ( + item.hasAttribute("data-level") && + +item.getAttribute("data-level") > lvl + ) + item.remove(); + }); + } + + //retrieve path, level and text + getElAtt(el) { + const newPath = el.getAttribute("data-path"); + const newLvl = el.getAttribute("data-level"); + const newTxt = el.getAttribute("data-name"); + return [newPath, newLvl, newTxt]; + } + + //hidden all folders + hiddenConfEls() { + this.els = document.querySelectorAll(`div[data-${this.prefix}-element]`); + this.els.forEach((el) => { + el.classList.add("hidden"); + el.removeAttribute("data-current-el"); + }); + } + + //add a bread item as last child with needed info + appendBreadItem(path, level, name) { + //create item el + const itemEl = document.createElement("li"); + itemEl.className = "leading-normal text-sm"; + //set item atts + const itemAtt = [ + ["data-path", path], + [`data-${this.prefix}-breadcrumb-item`, ""], + ["data-level", level], + ["data-name", name], + ]; + for (let i = 0; i < itemAtt.length; i++) { + itemEl.setAttribute(`${itemAtt[i][0]}`, `${itemAtt[i][1]}`); + } + //create nested btn el + const nestedBtnEl = document.createElement("button"); + nestedBtnEl.className = + "ml-2 dark:text-gray-500 text-gray-600 after:float-right after:pl-2 after:text-gray-600 dark:after:text-gray-500 after:content-['/']"; + itemEl.appendChild(nestedBtnEl); + nestedBtnEl.setAttribute("type", "button"); + nestedBtnEl.textContent = name; + this.breadContainer.appendChild(itemEl); + } +} + +class FolderDropdown { + constructor(prefix) { + this.prefix = prefix; + this.container = document.querySelector(`[data-${this.prefix}-container]`); + this.dropEls = document.querySelectorAll( + `[data-${this.prefix}-action-dropdown]`, + ); + this.init(); + } + + init() { + let prevActionBtn = ""; //compare with curr to hide or not prev + this.container.addEventListener("click", (e) => { + //remove when none click + try { + if ( + !e.target + .closest("div") + .hasAttribute(`data-${this.prefix}-action-button`) + ) { + this.hideDropEls(); + } + } catch (err) {} + //show dropdown actions for folders + try { + if ( + e.target + .closest("div") + .hasAttribute(`data-${this.prefix}-action-button`) + ) { + const dropEl = e.target + .closest(`div[data-${this.prefix}-element]`) + .querySelector(`[data-${this.prefix}-action-dropdown]`); + //avoid multiple dropdown + if (prevActionBtn === "") prevActionBtn = dropEl; + if (prevActionBtn !== dropEl) this.hideDropEls(); + this.toggleDrop(dropEl); + prevActionBtn = dropEl; + } + } catch (err) {} + //hide dropdown clicking an action + try { + if ( + e.target + .closest("button") + .hasAttribute(`data-${this.prefix}-action-dropdown-btn`) + ) { + const att = e.target + .closest("button") + .getAttribute(`data-${this.prefix}-action-dropdown-btn`); + const dropEl = document.querySelector( + `[data-${this.prefix}-action-dropdown="${att}"]`, + ); + this.hideDrop(dropEl); + } + } catch (err) {} + }); + } + + //UTILS + + toggleDrop(dropEl) { + dropEl.classList.toggle("hidden"); + dropEl.classList.toggle("flex"); + } + + hideDrop(dropEl) { + dropEl.classList.add("hidden"); + dropEl.classList.remove("flex"); + } + + hideDropEls() { + this.dropEls.forEach((drop) => { + this.hideDrop(drop); + }); + } +} + +class FolderEditor { + constructor() { + this.editor = ace.edit("editor"); + this.darkMode = document.querySelector("[data-dark-toggle]"); + this.initEditor(); + this.listenDarkToggle(); + } + + initEditor() { + //editor options + this.editor.setShowPrintMargin(false); + this.setDarkMode(); + } + + //listen to dark toggle button to change theme + listenDarkToggle() { + this.darkMode.addEventListener("click", (e) => { + this.darkMode.checked + ? this.changeDarkMode(true) + : this.changeDarkMode(false); + }); + } + + setDarkMode() { + document.querySelector("html").className.includes("dark") + ? this.editor.setTheme("ace/theme/dracula") + : this.editor.setTheme("ace/theme/dawn"); + } + + //change theme according to mode + changeDarkMode(bool) { + bool + ? this.editor.setTheme("ace/theme/dracula") + : this.editor.setTheme("ace/theme/dawn"); + } + + readOnlyBool(bool) { + this.editor.setReadOnly(bool); + } +} + +class FolderModal { + constructor(prefix) { + this.prefix = prefix; + //container + this.container = document.querySelector(`[data-${this.prefix}-container]`); + //add service/file elements + this.breadContainer = document.querySelector( + `[data-${this.prefix}-breadcrumb]`, + ); + this.addConfContainer = document.querySelector( + `[data-${this.prefix}-add-container]`, + ); + //modal DOM elements + this.form = document.querySelector(`[data-${this.prefix}-modal-form]`); + this.modalEl = document.querySelector(`[data-${this.prefix}-modal]`); + this.modalTitle = this.modalEl.querySelector( + `[data-${this.prefix}-modal-title]`, + ); + this.modalPath = this.modalEl.querySelector( + `[data-${this.prefix}-modal-path]`, + ); + this.modalEditor = this.modalEl.querySelector( + `[data-${this.prefix}-modal-editor]`, + ); + this.modalPathPrev = this.modalPath.querySelector( + `p[data-${this.prefix}-modal-path-prefix]`, + ); + this.modalPathName = this.modalPath.querySelector("input"); + this.modalPathSuffix = this.modalPath.querySelector( + `p[data-${this.prefix}-modal-path-suffix]`, + ); + + this.modalSubmit = this.modalEl.querySelector( + `[data-${this.prefix}-modal-submit]`, + ); + //hidden input for backend + this.modalInpPath = this.modalEl.querySelector("#path"); + this.modalInpOperation = this.modalEl.querySelector("#operation"); + this.modalInpType = this.modalEl.querySelector("#_type"); + this.modalInpOldName = this.modalEl.querySelector("#old_name"); + this.modalTxtarea = this.modalEl.querySelector("#content"); + //HANDLERS + //modal and values logic after clicking add file/folder button + this.initAddConfig(); + //modal and values logic after clicking actions buttons + this.initActionToModal(); + //modal element logic + this.initModal(); + //modal submit check and filter before submit + this.initForm(); + } + + //HANDLERS + initAddConfig() { + this.addConfContainer.addEventListener("click", (e) => { + //add folder + try { + if ( + e.target.closest("li").hasAttribute(`data-${this.prefix}-add-folder`) + ) { + this.setModal( + "new", + this.getPathFromBread(), + "folder", + "", + "", + this.getLevelFromBread(), + ); + } + } catch (err) {} + //add file + try { + if ( + e.target.closest("li").hasAttribute(`data-${this.prefix}-add-file`) + ) { + this.setModal( + "new", + this.getPathFromBread(), + "file", + "", + "", + this.getLevelFromBread(), + ); + } + } catch (err) {} + }); + } + + initActionToModal() { + this.container.addEventListener("click", (e) => { + //click on file logic + try { + if (e.target.closest("div").getAttribute("data-_type") == "file") { + const btnEl = e.target.closest("div").querySelector("button[value]"); + const [action, path, type, content, name, level] = + this.getInfoFromActionBtn(btnEl); + this.setModal(action, path, type, content, name, level); + this.showModal(); + } + } catch (err) {} + //set data of folder and show modal unless it's download btn + try { + if ( + e.target + .closest("button") + .hasAttribute(`data-${this.prefix}-action-dropdown-btn`) && + e.target.closest("button").getAttribute("value") !== "download" + ) { + const btnEl = e.target.closest("button"); + const [action, path, type, content, name, level] = + this.getInfoFromActionBtn(btnEl); + this.setModal(action, path, type, content, name, level); + this.showModal(); + } + } catch (err) {} + //download btn logic + try { + if ( + e.target + .closest("button") + .hasAttribute(`data-${this.prefix}-action-dropdown-btn`) && + e.target.closest("button").getAttribute("value") === "download" + ) { + const btnEl = e.target.closest("button"); + const [action, path, type, content, name, level] = + this.getInfoFromActionBtn(btnEl); + this.download(name, content); + } + } catch (err) {} + }); + } + + initModal() { + this.modalEl.addEventListener("click", (e) => { + //close modal logic + try { + if ( + e.target + .closest("button") + .hasAttribute(`data-${this.prefix}-modal-close`) + ) { + this.closeModal(); + } + } catch (err) {} + }); + } + + download(filename, text) { + var element = document.createElement("a"); + element.setAttribute( + "href", + "data:text/plain;charset=utf-8," + encodeURIComponent(text), + ); + element.setAttribute("download", filename); + + element.style.display = "none"; + document.body.appendChild(element); + + element.click(); + + document.body.removeChild(element); + } + + initForm() { + this.form.addEventListener("submit", (e) => { + e.preventDefault(); + //submit nothing case + if (this.modalInpOperation.value === "view") { + return this.closeModal(); + } + //else set data to input and request + this.setDataForRequest(); + }); + } + + //get data of custom inputs and set it on submit input + setDataForRequest() { + //set path to input + if (this.modalInpType === "folder") { + const prevPath = this.modalPathPrev.textContent; + const name = this.modalPathName.value; + this.modalInpPath.value = `${prevPath}${name}`; + } + //set textarea value from editor + const newTextarea = ace.edit("editor").getValue(); + this.modalTxtarea.value = newTextarea; + this.form.submit(); + } + + //for add file/folder btn + //get path of last bread element + getPathFromBread() { + const path = this.breadContainer.lastElementChild.getAttribute("data-path"); + return `${path}/`; + } + + getLevelFromBread() { + const level = + this.breadContainer.lastElementChild.getAttribute("data-level"); + return level; + } + //set all needed data from btn action and folder info + setModal(action, path, type, content, name, level) { + //title + this.modalTitle.textContent = `${action} ${type}`; + this.setInpt(action, path, type, name); + this.setEditor(type, content); + this.setSubmitTxt(action); + this.setPath(action, path, type, name, level); + this.setDisabled(action); + this.showModal(); + } + + //for hidden input to send on backend + //on form submit, check for update values before send request + setInpt(action, path, type, name) { + this.modalInpPath.value = + type === "file" && this.prefix === "configs" + ? path.replace(".conf", "") + : path; + this.modalInpType.value = type; + this.modalInpOperation.value = action; + this.modalInpOldName.value = + type === "file" && this.prefix === "configs" + ? name.replace(".conf", "") + : name; + } + + //path is empty if new one, else show current name + setPath(action, path, type) { + let [prevPath, name] = this.separatePath(path); + //remove conf if file type + this.modalPathSuffix.textContent = + type === "file" && this.prefix === "configs" ? ".conf" : ""; + name = + type === "file" && this.prefix === "configs" + ? name.replace(".conf", "") + : name; + + if (action === "new") { + this.modalPathPrev.textContent = `${path}`; + this.modalPathName.value = ``; + } + + if (action !== "new") { + this.modalPathPrev.textContent = `${prevPath}`; + this.modalPathName.value = `${name}`; + } + } + + //separate name and previous of path for DOM elements + separatePath(path) { + const splitPath = path.split("/"); + const nme = splitPath[splitPath.length - 1]; + const prev = path.replace(nme, ""); + return [prev, nme]; + } + + //disabled for view and delete actions + setDisabled(action) { + action === "view" || action === "delete" || action === "download" + ? this.disabledDOMInpt(true) + : this.disabledDOMInpt(false); + } + + //submit text depending action + setSubmitTxt(action) { + this.delSubmitBtnType(); + if (action === "new") { + this.modalSubmit.textContent = "add"; + this.setSubmitBtnType("valid-btn"); + return; + } + if (action === "view") { + this.modalSubmit.textContent = "ok"; + this.setSubmitBtnType("valid-btn"); + return; + } + if (action === "edit") { + this.setSubmitBtnType("edit-btn"); + this.modalSubmit.textContent = "edit"; + return; + } + + if (action === "delete") { + this.setSubmitBtnType("delete-btn"); + this.modalSubmit.textContent = "delete"; + return; + } + if (action === "download") { + this.setSubmitBtnType("info-btn"); + this.modalSubmit.textContent = "download"; + return; + } + } + + setSubmitBtnType(btnType) { + this.modalSubmit.classList.add(btnType); + } + + delSubmitBtnType() { + this.modalSubmit.classList.remove( + "delete-btn", + "valid-btn", + "edit-btn", + "info-btn", + ); + } + + //show only if type file and display text + setEditor(type, content) { + //SHOW LOGIC + if (type === "folder") this.modalEditor.classList.add("hidden"); + + if (type === "file") this.modalEditor.classList.remove("hidden"); + + ace.edit("editor").setValue(content); + } + + //get all needed info when clicking on action btn + getInfoFromActionBtn(btnEl) { + const action = btnEl.getAttribute("value"); + const name = btnEl.getAttribute(`data-${this.prefix}-action-dropdown-btn`); + const folder = btnEl.closest(`[data-${this.prefix}-element]`); + const level = folder.getAttribute("data-level"); + const path = folder.getAttribute("data-path"); + const type = folder.getAttribute("data-_type"); + let content; + try { + content = folder + .querySelector(`[data-${this.prefix}-content]`) + .getAttribute("data-value"); + } catch (err) { + content = ""; + } + return [action, path, type, content, name, level]; + } + + //UTILS + disabledDOMInpt(bool) { + this.modalPathName.disabled = bool; + ace.edit("editor").setReadOnly(bool); + } + + closeModal() { + this.modalEl.classList.add("hidden"); + this.modalEl.classList.remove("flex"); + } + + showModal() { + this.modalEl.classList.add("flex"); + this.modalEl.classList.remove("hidden"); + } +} + +export { FolderNav, FolderModal, FolderEditor, FolderDropdown }; diff --git a/src/ui/static/js/utils/form.js b/src/ui/static/js/utils/form.js index 5e6591263..1c50da357 100644 --- a/src/ui/static/js/utils/form.js +++ b/src/ui/static/js/utils/form.js @@ -1,262 +1,263 @@ -class Checkbox { - constructor() { - this.init(); - } - - init() { - window.addEventListener("click", (e) => { - //prevent default checkbox behavior - try { - //case a related checkbox element is clicked and checkbox is enabled - if ( - e.target.closest("div").hasAttribute("data-checkbox-handler") && - !e.target - .closest("div") - .querySelector('input[type="checkbox"]') - .hasAttribute("disabled") - ) { - //get related checkbox - const checkboxEl = e.target - .closest("div") - .querySelector('input[type="checkbox"]'); - - const prevValue = checkboxEl.getAttribute("value"); - - //set attribute value for new state - prevValue === "no" - ? checkboxEl.setAttribute("value", "yes") - : checkboxEl.setAttribute("value", "no"); - - //set custom input hidden value - const newValue = checkboxEl.getAttribute("value"); - newValue === "yes" - ? checkboxEl.setAttribute("aria-checked", "true") - : checkboxEl.setAttribute("aria-checked", "false"); - - //force checked for submit - checkboxEl.checked = true; - } - } catch (err) {} - }); - } -} - -class Select { - constructor() { - this.init(); - } - - init() { - window.addEventListener("click", (e) => { - //CASE NO BTN SELECT CLICKED - try { - if (!e.target.closest("button")) { - const selectEls = document.querySelectorAll( - "div[data-setting-select-dropdown]" - ); - selectEls.forEach((select) => { - select.classList.add("hidden"); - select.classList.remove("flex"); - }); - const btnEls = document.querySelectorAll( - "button[data-setting-select]" - ); - btnEls.forEach((btn) => { - const dropdownChevron = btn.querySelector( - `svg[data-setting-select]` - ); - dropdownChevron.classList.remove("rotate-180"); - }); - } - } catch (err) {} - //SELECT BTN LOGIC - try { - if ( - e.target.closest("button").hasAttribute(`data-setting-select`) && - !e.target.closest("button").hasAttribute(`disabled`) - ) { - const btnEl = e.target.closest("button"); - this.toggleSelectBtn(btnEl); - } - } catch (err) {} - //SELECT DROPDOWN BTN LOGIC - try { - if ( - e.target - .closest("button") - .hasAttribute(`data-setting-select-dropdown-btn`) - ) { - const btn = e.target.closest( - `button[data-setting-select-dropdown-btn]` - ); - const btnValue = btn.getAttribute("value"); - - //add new value to custom - const selectCustom = btn - .closest("div[data-select-container]") - .querySelector(`button[data-setting-select]`); - - selectCustom.querySelector(`[data-setting-select-text]`).textContent = - btnValue; - //add selected to new value - - //change style - const dropdownEl = btn.closest(`div[data-setting-select-dropdown]`); - dropdownEl.classList.add("hidden"); - dropdownEl.classList.remove("flex"); - - //reset dropdown btns - const btnEls = dropdownEl.querySelectorAll("button"); - - btnEls.forEach((btn) => { - btn.classList.remove("active"); - }); - //highlight clicked btn - btn.classList.add("active"); - - //close dropdown - const dropdownChevron = selectCustom.querySelector( - `svg[data-setting-select]` - ); - dropdownChevron.classList.remove("rotate-180"); - - //update real select element - const realSel = btn - .closest("div[data-setting-container]") - .querySelector("select"); - this.updateSelected(realSel, btnValue); - } - } catch (err) {} - }); - } - - updateSelected(selectEl, selectedValue) { - const options = selectEl.querySelectorAll("option"); - //remove selected to all - options.forEach((option) => { - option.removeAttribute("selected"); - option.selected = false; - }); - //select new one - const newOption = selectEl.querySelector( - `option[value="${selectedValue}"]` - ); - newOption.selected = true; - newOption.setAttribute("selected", ""); - } - - toggleSelectBtn(btn) { - //toggle dropdown - const dropdownEl = btn - .closest("div") - .querySelector(`[data-setting-select-dropdown]`); - const dropdownChevron = btn.querySelector(`svg[data-setting-select]`); - dropdownEl.classList.toggle("hidden"); - dropdownEl.classList.toggle("flex"); - dropdownChevron.classList.toggle("rotate-180"); - } -} - -class Password { - constructor() { - this.init(); - } - - init() { - window.addEventListener("click", (e) => { - try { - if (e.target.closest("button").hasAttribute("data-setting-password")) { - const btn = e.target.closest("button"); - const action = btn.getAttribute("data-setting-password"); - const inp = btn - .closest("[data-setting-container]") - .querySelector("input"); - this.setValDisplay(action, inp); - this.hiddenBtns(btn); - this.showOppositeBtn(btn, action); - } - } catch (err) {} - }); - } - - showOppositeBtn(btnEl, action) { - const btnEls = this.getBtns(btnEl); - const opposite = action === "visible" ? "invisible" : "visible"; - - btnEls.forEach((btn) => { - const action = btn.getAttribute("data-setting-password"); - - if (action === opposite) { - btn.classList.add("flex"); - btn.classList.remove("hidden"); - } - }); - } - - setValDisplay(action, inp) { - if (action === "visible") inp.setAttribute("type", "text"); - if (action === "invisible") inp.setAttribute("type", "password"); - } - - hiddenBtns(btnEl) { - const btnEls = this.getBtns(btnEl); - - btnEls.forEach((btn) => { - btn.classList.add("hidden"); - btn.classList.remove("flex"); - }); - } - - getBtns(btnEl) { - return btnEl - .closest("[data-setting-container]") - .querySelectorAll("button[data-setting-password]"); - } -} - -class DisabledPop { - constructor() { - this.init(); - } - - init() { - window.addEventListener("pointerover", (e) => { - //for checkbox and regular inputs - if (e.target.tagName === "INPUT") { - const el = e.target; - this.showPopup(el, "input"); - } - //for select custom - if ( - e.target.tagName === "BUTTON" && - e.target.hasAttribute("data-setting-select") - ) { - const el = e.target; - this.showPopup(el, "select"); - } - }); - - window.addEventListener("pointerout", (e) => { - try { - const popupEl = e.target - .closest("div") - .querySelector("div[data-disabled-info]"); - popupEl.remove(); - } catch (err) {} - }); - } - - showPopup(el, type = "input") { - if (!el.hasAttribute("disabled")) return; - const method = el.getAttribute("data-default-method"); - const popupHTML = ` -
-

disabled by ${method}

-
`; - el.insertAdjacentHTML("beforebegin", popupHTML); - } -} - -export { Checkbox, Select, Password, DisabledPop }; +class Checkbox { + constructor() { + this.init(); + } + + init() { + window.addEventListener("click", (e) => { + //prevent default checkbox behavior + try { + //case a related checkbox element is clicked and checkbox is enabled + if ( + e.target.closest("div").hasAttribute("data-checkbox-handler") && + !e.target + .closest("div") + .querySelector('input[type="checkbox"]') + .hasAttribute("disabled") + ) { + //get related checkbox + const checkboxEl = e.target + .closest("div") + .querySelector('input[type="checkbox"]'); + + const prevValue = checkboxEl.getAttribute("value"); + + //set attribute value for new state + prevValue === "no" + ? checkboxEl.setAttribute("value", "yes") + : checkboxEl.setAttribute("value", "no"); + + //set custom input hidden value + const newValue = checkboxEl.getAttribute("value"); + newValue === "yes" + ? checkboxEl.setAttribute("aria-checked", "true") + : checkboxEl.setAttribute("aria-checked", "false"); + + //force checked for submit + checkboxEl.checked = true; + } + } catch (err) {} + }); + } +} + +class Select { + constructor() { + this.init(); + } + + init() { + window.addEventListener("click", (e) => { + //CASE NO BTN SELECT CLICKED + try { + if (!e.target.closest("button")) { + const selectEls = document.querySelectorAll( + "div[data-setting-select-dropdown]" + ); + selectEls.forEach((select) => { + select.classList.add("hidden"); + select.classList.remove("flex"); + }); + const btnEls = document.querySelectorAll( + "button[data-setting-select]" + ); + btnEls.forEach((btn) => { + const dropdownChevron = btn.querySelector( + `svg[data-setting-select]` + ); + dropdownChevron.classList.remove("rotate-180"); + }); + } + } catch (err) {} + //SELECT BTN LOGIC + try { + if ( + e.target.closest("button").hasAttribute(`data-setting-select`) && + !e.target.closest("button").hasAttribute(`disabled`) + ) { + const btnEl = e.target.closest("button"); + this.toggleSelectBtn(btnEl); + } + } catch (err) {} + //SELECT DROPDOWN BTN LOGIC + try { + if ( + e.target + .closest("button") + .hasAttribute(`data-setting-select-dropdown-btn`) + ) { + const btn = e.target.closest( + `button[data-setting-select-dropdown-btn]` + ); + const btnValue = btn.getAttribute("value"); + + //add new value to custom + const selectCustom = btn + .closest("div[data-select-container]") + .querySelector(`button[data-setting-select]`); + + selectCustom.querySelector(`[data-setting-select-text]`).textContent = + btnValue; + //add selected to new value + + //change style + const dropdownEl = btn.closest(`div[data-setting-select-dropdown]`); + dropdownEl.classList.add("hidden"); + dropdownEl.classList.remove("flex"); + + //reset dropdown btns + const btnEls = dropdownEl.querySelectorAll("button"); + + btnEls.forEach((btn) => { + btn.classList.remove("active"); + }); + //highlight clicked btn + btn.classList.add("active"); + + //close dropdown + const dropdownChevron = selectCustom.querySelector( + `svg[data-setting-select]` + ); + dropdownChevron.classList.remove("rotate-180"); + + //update real select element + const realSel = btn + .closest("div[data-setting-container]") + .querySelector("select"); + this.updateSelected(realSel, btnValue); + } + } catch (err) {} + }); + } + + updateSelected(selectEl, selectedValue) { + const options = selectEl.querySelectorAll("option"); + //remove selected to all + options.forEach((option) => { + option.removeAttribute("selected"); + option.selected = false; + }); + //select new one + const newOption = selectEl.querySelector( + `option[value="${selectedValue}"]` + ); + newOption.selected = true; + newOption.setAttribute("selected", ""); + } + + toggleSelectBtn(btn) { + //toggle dropdown + const dropdownEl = btn + .closest("div") + .querySelector(`[data-setting-select-dropdown]`); + const dropdownChevron = btn.querySelector(`svg[data-setting-select]`); + dropdownEl.classList.toggle("hidden"); + dropdownEl.classList.toggle("flex"); + dropdownChevron.classList.toggle("rotate-180"); + } +} + +class Password { + constructor() { + this.init(); + } + + init() { + window.addEventListener("click", (e) => { + try { + if (e.target.closest("button").hasAttribute("data-setting-password")) { + const btn = e.target.closest("button"); + const action = btn.getAttribute("data-setting-password"); + const inp = btn + .closest("[data-setting-container]") + .querySelector("input"); + this.setValDisplay(action, inp); + this.hiddenBtns(btn); + this.showOppositeBtn(btn, action); + } + } catch (err) {} + }); + } + + showOppositeBtn(btnEl, action) { + const btnEls = this.getBtns(btnEl); + const opposite = action === "visible" ? "invisible" : "visible"; + + btnEls.forEach((btn) => { + const action = btn.getAttribute("data-setting-password"); + + if (action === opposite) { + btn.classList.add("flex"); + btn.classList.remove("hidden"); + } + }); + } + + setValDisplay(action, inp) { + if (action === "visible") inp.setAttribute("type", "text"); + if (action === "invisible") inp.setAttribute("type", "password"); + } + + hiddenBtns(btnEl) { + const btnEls = this.getBtns(btnEl); + + btnEls.forEach((btn) => { + btn.classList.add("hidden"); + btn.classList.remove("flex"); + }); + } + + getBtns(btnEl) { + return btnEl + .closest("[data-setting-container]") + .querySelectorAll("button[data-setting-password]"); + } +} + +class DisabledPop { + constructor() { + this.init(); + } + + init() { + window.addEventListener("pointerover", (e) => { + //for checkbox and regular inputs + if (e.target.tagName === "INPUT") { + const el = e.target; + this.showPopup(el, "input"); + } + //for select custom + if ( + e.target.tagName === "BUTTON" && + e.target.hasAttribute("data-setting-select") + ) { + const el = e.target; + this.showPopup(el, "select"); + } + }); + + window.addEventListener("pointerout", (e) => { + try { + const popupEl = e.target + .closest("div") + .querySelector("div[data-disabled-info]"); + popupEl.remove(); + } catch (err) {} + }); + } + + showPopup(el, type = "input") { + if (!el.hasAttribute("disabled")) return; + const method = el.getAttribute("data-default-method"); + const popupHTML = ` +
+

disabled by ${method}

+
`; + let cleanHTML = DOMPurify.sanitize(popupHTML); + el.insertAdjacentHTML("beforebegin", cleanHTML); + } +} + +export { Checkbox, Select, Password, DisabledPop }; diff --git a/src/ui/static/js/utils/purify/purify.min.js b/src/ui/static/js/utils/purify/purify.min.js new file mode 100644 index 000000000..7a4da7686 --- /dev/null +++ b/src/ui/static/js/utils/purify/purify.min.js @@ -0,0 +1,3 @@ +/*! @license DOMPurify 3.0.6 | (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.6/LICENSE */ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).DOMPurify=t()}(this,(function(){"use strict";const{entries:e,setPrototypeOf:t,isFrozen:n,getPrototypeOf:o,getOwnPropertyDescriptor:r}=Object;let{freeze:i,seal:a,create:l}=Object,{apply:c,construct:s}="undefined"!=typeof Reflect&&Reflect;i||(i=function(e){return e}),a||(a=function(e){return e}),c||(c=function(e,t,n){return e.apply(t,n)}),s||(s=function(e,t){return new e(...t)});const u=N(Array.prototype.forEach),m=N(Array.prototype.pop),f=N(Array.prototype.push),p=N(String.prototype.toLowerCase),d=N(String.prototype.toString),h=N(String.prototype.match),g=N(String.prototype.replace),T=N(String.prototype.indexOf),y=N(String.prototype.trim),E=N(RegExp.prototype.test),A=(_=TypeError,function(){for(var e=arguments.length,t=new Array(e),n=0;n1?n-1:0),r=1;r2&&void 0!==arguments[2]?arguments[2]:p;t&&t(e,null);let i=o.length;for(;i--;){let t=o[i];if("string"==typeof t){const e=r(t);e!==t&&(n(o)||(o[i]=e),t=e)}e[t]=!0}return e}function S(t){const n=l(null);for(const[o,i]of e(t))void 0!==r(t,o)&&(n[o]=i);return n}function R(e,t){for(;null!==e;){const n=r(e,t);if(n){if(n.get)return N(n.get);if("function"==typeof n.value)return N(n.value)}e=o(e)}return function(e){return console.warn("fallback value for",e),null}}const w=i(["a","abbr","acronym","address","area","article","aside","audio","b","bdi","bdo","big","blink","blockquote","body","br","button","canvas","caption","center","cite","code","col","colgroup","content","data","datalist","dd","decorator","del","details","dfn","dialog","dir","div","dl","dt","element","em","fieldset","figcaption","figure","font","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","img","input","ins","kbd","label","legend","li","main","map","mark","marquee","menu","menuitem","meter","nav","nobr","ol","optgroup","option","output","p","picture","pre","progress","q","rp","rt","ruby","s","samp","section","select","shadow","small","source","spacer","span","strike","strong","style","sub","summary","sup","table","tbody","td","template","textarea","tfoot","th","thead","time","tr","track","tt","u","ul","var","video","wbr"]),D=i(["svg","a","altglyph","altglyphdef","altglyphitem","animatecolor","animatemotion","animatetransform","circle","clippath","defs","desc","ellipse","filter","font","g","glyph","glyphref","hkern","image","line","lineargradient","marker","mask","metadata","mpath","path","pattern","polygon","polyline","radialgradient","rect","stop","style","switch","symbol","text","textpath","title","tref","tspan","view","vkern"]),L=i(["feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feDropShadow","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence"]),v=i(["animate","color-profile","cursor","discard","font-face","font-face-format","font-face-name","font-face-src","font-face-uri","foreignobject","hatch","hatchpath","mesh","meshgradient","meshpatch","meshrow","missing-glyph","script","set","solidcolor","unknown","use"]),x=i(["math","menclose","merror","mfenced","mfrac","mglyph","mi","mlabeledtr","mmultiscripts","mn","mo","mover","mpadded","mphantom","mroot","mrow","ms","mspace","msqrt","mstyle","msub","msup","msubsup","mtable","mtd","mtext","mtr","munder","munderover","mprescripts"]),k=i(["maction","maligngroup","malignmark","mlongdiv","mscarries","mscarry","msgroup","mstack","msline","msrow","semantics","annotation","annotation-xml","mprescripts","none"]),C=i(["#text"]),O=i(["accept","action","align","alt","autocapitalize","autocomplete","autopictureinpicture","autoplay","background","bgcolor","border","capture","cellpadding","cellspacing","checked","cite","class","clear","color","cols","colspan","controls","controlslist","coords","crossorigin","datetime","decoding","default","dir","disabled","disablepictureinpicture","disableremoteplayback","download","draggable","enctype","enterkeyhint","face","for","headers","height","hidden","high","href","hreflang","id","inputmode","integrity","ismap","kind","label","lang","list","loading","loop","low","max","maxlength","media","method","min","minlength","multiple","muted","name","nonce","noshade","novalidate","nowrap","open","optimum","pattern","placeholder","playsinline","poster","preload","pubdate","radiogroup","readonly","rel","required","rev","reversed","role","rows","rowspan","spellcheck","scope","selected","shape","size","sizes","span","srclang","start","src","srcset","step","style","summary","tabindex","title","translate","type","usemap","valign","value","width","xmlns","slot"]),I=i(["accent-height","accumulate","additive","alignment-baseline","ascent","attributename","attributetype","azimuth","basefrequency","baseline-shift","begin","bias","by","class","clip","clippathunits","clip-path","clip-rule","color","color-interpolation","color-interpolation-filters","color-profile","color-rendering","cx","cy","d","dx","dy","diffuseconstant","direction","display","divisor","dur","edgemode","elevation","end","fill","fill-opacity","fill-rule","filter","filterunits","flood-color","flood-opacity","font-family","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-weight","fx","fy","g1","g2","glyph-name","glyphref","gradientunits","gradienttransform","height","href","id","image-rendering","in","in2","k","k1","k2","k3","k4","kerning","keypoints","keysplines","keytimes","lang","lengthadjust","letter-spacing","kernelmatrix","kernelunitlength","lighting-color","local","marker-end","marker-mid","marker-start","markerheight","markerunits","markerwidth","maskcontentunits","maskunits","max","mask","media","method","mode","min","name","numoctaves","offset","operator","opacity","order","orient","orientation","origin","overflow","paint-order","path","pathlength","patterncontentunits","patterntransform","patternunits","points","preservealpha","preserveaspectratio","primitiveunits","r","rx","ry","radius","refx","refy","repeatcount","repeatdur","restart","result","rotate","scale","seed","shape-rendering","specularconstant","specularexponent","spreadmethod","startoffset","stddeviation","stitchtiles","stop-color","stop-opacity","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke","stroke-width","style","surfacescale","systemlanguage","tabindex","targetx","targety","transform","transform-origin","text-anchor","text-decoration","text-rendering","textlength","type","u1","u2","unicode","values","viewbox","visibility","version","vert-adv-y","vert-origin-x","vert-origin-y","width","word-spacing","wrap","writing-mode","xchannelselector","ychannelselector","x","x1","x2","xmlns","y","y1","y2","z","zoomandpan"]),M=i(["accent","accentunder","align","bevelled","close","columnsalign","columnlines","columnspan","denomalign","depth","dir","display","displaystyle","encoding","fence","frame","height","href","id","largeop","length","linethickness","lspace","lquote","mathbackground","mathcolor","mathsize","mathvariant","maxsize","minsize","movablelimits","notation","numalign","open","rowalign","rowlines","rowspacing","rowspan","rspace","rquote","scriptlevel","scriptminsize","scriptsizemultiplier","selection","separator","separators","stretchy","subscriptshift","supscriptshift","symmetric","voffset","width","xmlns"]),U=i(["xlink:href","xml:id","xlink:title","xml:space","xmlns:xlink"]),P=a(/\{\{[\w\W]*|[\w\W]*\}\}/gm),F=a(/<%[\w\W]*|[\w\W]*%>/gm),H=a(/\${[\w\W]*}/gm),z=a(/^data-[\-\w.\u00B7-\uFFFF]/),B=a(/^aria-[\-\w]+$/),W=a(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),G=a(/^(?:\w+script|data):/i),Y=a(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),j=a(/^html$/i);var q=Object.freeze({__proto__:null,MUSTACHE_EXPR:P,ERB_EXPR:F,TMPLIT_EXPR:H,DATA_ATTR:z,ARIA_ATTR:B,IS_ALLOWED_URI:W,IS_SCRIPT_OR_DATA:G,ATTR_WHITESPACE:Y,DOCTYPE_NAME:j});const X=function(){return"undefined"==typeof window?null:window},K=function(e,t){if("object"!=typeof e||"function"!=typeof e.createPolicy)return null;let n=null;const o="data-tt-policy-suffix";t&&t.hasAttribute(o)&&(n=t.getAttribute(o));const r="dompurify"+(n?"#"+n:"");try{return e.createPolicy(r,{createHTML:e=>e,createScriptURL:e=>e})}catch(e){return console.warn("TrustedTypes policy "+r+" could not be created."),null}};var V=function t(){let n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:X();const o=e=>t(e);if(o.version="3.0.6",o.removed=[],!n||!n.document||9!==n.document.nodeType)return o.isSupported=!1,o;let{document:r}=n;const a=r,c=a.currentScript,{DocumentFragment:s,HTMLTemplateElement:_,Node:N,Element:P,NodeFilter:F,NamedNodeMap:H=n.NamedNodeMap||n.MozNamedAttrMap,HTMLFormElement:z,DOMParser:B,trustedTypes:G}=n,Y=P.prototype,V=R(Y,"cloneNode"),$=R(Y,"nextSibling"),Z=R(Y,"childNodes"),J=R(Y,"parentNode");if("function"==typeof _){const e=r.createElement("template");e.content&&e.content.ownerDocument&&(r=e.content.ownerDocument)}let Q,ee="";const{implementation:te,createNodeIterator:ne,createDocumentFragment:oe,getElementsByTagName:re}=r,{importNode:ie}=a;let ae={};o.isSupported="function"==typeof e&&"function"==typeof J&&te&&void 0!==te.createHTMLDocument;const{MUSTACHE_EXPR:le,ERB_EXPR:ce,TMPLIT_EXPR:se,DATA_ATTR:ue,ARIA_ATTR:me,IS_SCRIPT_OR_DATA:fe,ATTR_WHITESPACE:pe}=q;let{IS_ALLOWED_URI:de}=q,he=null;const ge=b({},[...w,...D,...L,...x,...C]);let Te=null;const ye=b({},[...O,...I,...M,...U]);let Ee=Object.seal(l(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}})),Ae=null,_e=null,Ne=!0,be=!0,Se=!1,Re=!0,we=!1,De=!1,Le=!1,ve=!1,xe=!1,ke=!1,Ce=!1,Oe=!0,Ie=!1;const Me="user-content-";let Ue=!0,Pe=!1,Fe={},He=null;const ze=b({},["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 Be=null;const We=b({},["audio","video","img","source","image","track"]);let Ge=null;const Ye=b({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),je="http://www.w3.org/1998/Math/MathML",qe="http://www.w3.org/2000/svg",Xe="http://www.w3.org/1999/xhtml";let Ke=Xe,Ve=!1,$e=null;const Ze=b({},[je,qe,Xe],d);let Je=null;const Qe=["application/xhtml+xml","text/html"],et="text/html";let tt=null,nt=null;const ot=r.createElement("form"),rt=function(e){return e instanceof RegExp||e instanceof Function},it=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(!nt||nt!==e){if(e&&"object"==typeof e||(e={}),e=S(e),Je=Je=-1===Qe.indexOf(e.PARSER_MEDIA_TYPE)?et:e.PARSER_MEDIA_TYPE,tt="application/xhtml+xml"===Je?d:p,he="ALLOWED_TAGS"in e?b({},e.ALLOWED_TAGS,tt):ge,Te="ALLOWED_ATTR"in e?b({},e.ALLOWED_ATTR,tt):ye,$e="ALLOWED_NAMESPACES"in e?b({},e.ALLOWED_NAMESPACES,d):Ze,Ge="ADD_URI_SAFE_ATTR"in e?b(S(Ye),e.ADD_URI_SAFE_ATTR,tt):Ye,Be="ADD_DATA_URI_TAGS"in e?b(S(We),e.ADD_DATA_URI_TAGS,tt):We,He="FORBID_CONTENTS"in e?b({},e.FORBID_CONTENTS,tt):ze,Ae="FORBID_TAGS"in e?b({},e.FORBID_TAGS,tt):{},_e="FORBID_ATTR"in e?b({},e.FORBID_ATTR,tt):{},Fe="USE_PROFILES"in e&&e.USE_PROFILES,Ne=!1!==e.ALLOW_ARIA_ATTR,be=!1!==e.ALLOW_DATA_ATTR,Se=e.ALLOW_UNKNOWN_PROTOCOLS||!1,Re=!1!==e.ALLOW_SELF_CLOSE_IN_ATTR,we=e.SAFE_FOR_TEMPLATES||!1,De=e.WHOLE_DOCUMENT||!1,xe=e.RETURN_DOM||!1,ke=e.RETURN_DOM_FRAGMENT||!1,Ce=e.RETURN_TRUSTED_TYPE||!1,ve=e.FORCE_BODY||!1,Oe=!1!==e.SANITIZE_DOM,Ie=e.SANITIZE_NAMED_PROPS||!1,Ue=!1!==e.KEEP_CONTENT,Pe=e.IN_PLACE||!1,de=e.ALLOWED_URI_REGEXP||W,Ke=e.NAMESPACE||Xe,Ee=e.CUSTOM_ELEMENT_HANDLING||{},e.CUSTOM_ELEMENT_HANDLING&&rt(e.CUSTOM_ELEMENT_HANDLING.tagNameCheck)&&(Ee.tagNameCheck=e.CUSTOM_ELEMENT_HANDLING.tagNameCheck),e.CUSTOM_ELEMENT_HANDLING&&rt(e.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)&&(Ee.attributeNameCheck=e.CUSTOM_ELEMENT_HANDLING.attributeNameCheck),e.CUSTOM_ELEMENT_HANDLING&&"boolean"==typeof e.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements&&(Ee.allowCustomizedBuiltInElements=e.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements),we&&(be=!1),ke&&(xe=!0),Fe&&(he=b({},[...C]),Te=[],!0===Fe.html&&(b(he,w),b(Te,O)),!0===Fe.svg&&(b(he,D),b(Te,I),b(Te,U)),!0===Fe.svgFilters&&(b(he,L),b(Te,I),b(Te,U)),!0===Fe.mathMl&&(b(he,x),b(Te,M),b(Te,U))),e.ADD_TAGS&&(he===ge&&(he=S(he)),b(he,e.ADD_TAGS,tt)),e.ADD_ATTR&&(Te===ye&&(Te=S(Te)),b(Te,e.ADD_ATTR,tt)),e.ADD_URI_SAFE_ATTR&&b(Ge,e.ADD_URI_SAFE_ATTR,tt),e.FORBID_CONTENTS&&(He===ze&&(He=S(He)),b(He,e.FORBID_CONTENTS,tt)),Ue&&(he["#text"]=!0),De&&b(he,["html","head","body"]),he.table&&(b(he,["tbody"]),delete Ae.tbody),e.TRUSTED_TYPES_POLICY){if("function"!=typeof e.TRUSTED_TYPES_POLICY.createHTML)throw A('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');if("function"!=typeof e.TRUSTED_TYPES_POLICY.createScriptURL)throw A('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');Q=e.TRUSTED_TYPES_POLICY,ee=Q.createHTML("")}else void 0===Q&&(Q=K(G,c)),null!==Q&&"string"==typeof ee&&(ee=Q.createHTML(""));i&&i(e),nt=e}},at=b({},["mi","mo","mn","ms","mtext"]),lt=b({},["foreignobject","desc","title","annotation-xml"]),ct=b({},["title","style","font","a","script"]),st=b({},D);b(st,L),b(st,v);const ut=b({},x);b(ut,k);const mt=function(e){let t=J(e);t&&t.tagName||(t={namespaceURI:Ke,tagName:"template"});const n=p(e.tagName),o=p(t.tagName);return!!$e[e.namespaceURI]&&(e.namespaceURI===qe?t.namespaceURI===Xe?"svg"===n:t.namespaceURI===je?"svg"===n&&("annotation-xml"===o||at[o]):Boolean(st[n]):e.namespaceURI===je?t.namespaceURI===Xe?"math"===n:t.namespaceURI===qe?"math"===n&<[o]:Boolean(ut[n]):e.namespaceURI===Xe?!(t.namespaceURI===qe&&!lt[o])&&(!(t.namespaceURI===je&&!at[o])&&(!ut[n]&&(ct[n]||!st[n]))):!("application/xhtml+xml"!==Je||!$e[e.namespaceURI]))},ft=function(e){f(o.removed,{element:e});try{e.parentNode.removeChild(e)}catch(t){e.remove()}},pt=function(e,t){try{f(o.removed,{attribute:t.getAttributeNode(e),from:t})}catch(e){f(o.removed,{attribute:null,from:t})}if(t.removeAttribute(e),"is"===e&&!Te[e])if(xe||ke)try{ft(t)}catch(e){}else try{t.setAttribute(e,"")}catch(e){}},dt=function(e){let t=null,n=null;if(ve)e=""+e;else{const t=h(e,/^[\r\n\t ]+/);n=t&&t[0]}"application/xhtml+xml"===Je&&Ke===Xe&&(e=''+e+"");const o=Q?Q.createHTML(e):e;if(Ke===Xe)try{t=(new B).parseFromString(o,Je)}catch(e){}if(!t||!t.documentElement){t=te.createDocument(Ke,"template",null);try{t.documentElement.innerHTML=Ve?ee:o}catch(e){}}const i=t.body||t.documentElement;return e&&n&&i.insertBefore(r.createTextNode(n),i.childNodes[0]||null),Ke===Xe?re.call(t,De?"html":"body")[0]:De?t.documentElement:i},ht=function(e){return ne.call(e.ownerDocument||e,e,F.SHOW_ELEMENT|F.SHOW_COMMENT|F.SHOW_TEXT,null)},gt=function(e){return e instanceof z&&("string"!=typeof e.nodeName||"string"!=typeof e.textContent||"function"!=typeof e.removeChild||!(e.attributes instanceof H)||"function"!=typeof e.removeAttribute||"function"!=typeof e.setAttribute||"string"!=typeof e.namespaceURI||"function"!=typeof e.insertBefore||"function"!=typeof e.hasChildNodes)},Tt=function(e){return"function"==typeof N&&e instanceof N},yt=function(e,t,n){ae[e]&&u(ae[e],(e=>{e.call(o,t,n,nt)}))},Et=function(e){let t=null;if(yt("beforeSanitizeElements",e,null),gt(e))return ft(e),!0;const n=tt(e.nodeName);if(yt("uponSanitizeElement",e,{tagName:n,allowedTags:he}),e.hasChildNodes()&&!Tt(e.firstElementChild)&&E(/<[/\w]/g,e.innerHTML)&&E(/<[/\w]/g,e.textContent))return ft(e),!0;if(!he[n]||Ae[n]){if(!Ae[n]&&_t(n)){if(Ee.tagNameCheck instanceof RegExp&&E(Ee.tagNameCheck,n))return!1;if(Ee.tagNameCheck instanceof Function&&Ee.tagNameCheck(n))return!1}if(Ue&&!He[n]){const t=J(e)||e.parentNode,n=Z(e)||e.childNodes;if(n&&t){for(let o=n.length-1;o>=0;--o)t.insertBefore(V(n[o],!0),$(e))}}return ft(e),!0}return e instanceof P&&!mt(e)?(ft(e),!0):"noscript"!==n&&"noembed"!==n&&"noframes"!==n||!E(/<\/no(script|embed|frames)/i,e.innerHTML)?(we&&3===e.nodeType&&(t=e.textContent,u([le,ce,se],(e=>{t=g(t,e," ")})),e.textContent!==t&&(f(o.removed,{element:e.cloneNode()}),e.textContent=t)),yt("afterSanitizeElements",e,null),!1):(ft(e),!0)},At=function(e,t,n){if(Oe&&("id"===t||"name"===t)&&(n in r||n in ot))return!1;if(be&&!_e[t]&&E(ue,t));else if(Ne&&E(me,t));else if(!Te[t]||_e[t]){if(!(_t(e)&&(Ee.tagNameCheck instanceof RegExp&&E(Ee.tagNameCheck,e)||Ee.tagNameCheck instanceof Function&&Ee.tagNameCheck(e))&&(Ee.attributeNameCheck instanceof RegExp&&E(Ee.attributeNameCheck,t)||Ee.attributeNameCheck instanceof Function&&Ee.attributeNameCheck(t))||"is"===t&&Ee.allowCustomizedBuiltInElements&&(Ee.tagNameCheck instanceof RegExp&&E(Ee.tagNameCheck,n)||Ee.tagNameCheck instanceof Function&&Ee.tagNameCheck(n))))return!1}else if(Ge[t]);else if(E(de,g(n,pe,"")));else if("src"!==t&&"xlink:href"!==t&&"href"!==t||"script"===e||0!==T(n,"data:")||!Be[e]){if(Se&&!E(fe,g(n,pe,"")));else if(n)return!1}else;return!0},_t=function(e){return e.indexOf("-")>0},Nt=function(e){yt("beforeSanitizeAttributes",e,null);const{attributes:t}=e;if(!t)return;const n={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:Te};let r=t.length;for(;r--;){const i=t[r],{name:a,namespaceURI:l,value:c}=i,s=tt(a);let f="value"===a?c:y(c);if(n.attrName=s,n.attrValue=f,n.keepAttr=!0,n.forceKeepAttr=void 0,yt("uponSanitizeAttribute",e,n),f=n.attrValue,n.forceKeepAttr)continue;if(pt(a,e),!n.keepAttr)continue;if(!Re&&E(/\/>/i,f)){pt(a,e);continue}we&&u([le,ce,se],(e=>{f=g(f,e," ")}));const p=tt(e.nodeName);if(At(p,s,f)){if(!Ie||"id"!==s&&"name"!==s||(pt(a,e),f=Me+f),Q&&"object"==typeof G&&"function"==typeof G.getAttributeType)if(l);else switch(G.getAttributeType(p,s)){case"TrustedHTML":f=Q.createHTML(f);break;case"TrustedScriptURL":f=Q.createScriptURL(f)}try{l?e.setAttributeNS(l,a,f):e.setAttribute(a,f),m(o.removed)}catch(e){}}}yt("afterSanitizeAttributes",e,null)},bt=function e(t){let n=null;const o=ht(t);for(yt("beforeSanitizeShadowDOM",t,null);n=o.nextNode();)yt("uponSanitizeShadowNode",n,null),Et(n)||(n.content instanceof s&&e(n.content),Nt(n));yt("afterSanitizeShadowDOM",t,null)};return o.sanitize=function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=null,r=null,i=null,l=null;if(Ve=!e,Ve&&(e="\x3c!--\x3e"),"string"!=typeof e&&!Tt(e)){if("function"!=typeof e.toString)throw A("toString is not a function");if("string"!=typeof(e=e.toString()))throw A("dirty is not a string, aborting")}if(!o.isSupported)return e;if(Le||it(t),o.removed=[],"string"==typeof e&&(Pe=!1),Pe){if(e.nodeName){const t=tt(e.nodeName);if(!he[t]||Ae[t])throw A("root node is forbidden and cannot be sanitized in-place")}}else if(e instanceof N)n=dt("\x3c!----\x3e"),r=n.ownerDocument.importNode(e,!0),1===r.nodeType&&"BODY"===r.nodeName||"HTML"===r.nodeName?n=r:n.appendChild(r);else{if(!xe&&!we&&!De&&-1===e.indexOf("<"))return Q&&Ce?Q.createHTML(e):e;if(n=dt(e),!n)return xe?null:Ce?ee:""}n&&ve&&ft(n.firstChild);const c=ht(Pe?e:n);for(;i=c.nextNode();)Et(i)||(i.content instanceof s&&bt(i.content),Nt(i));if(Pe)return e;if(xe){if(ke)for(l=oe.call(n.ownerDocument);n.firstChild;)l.appendChild(n.firstChild);else l=n;return(Te.shadowroot||Te.shadowrootmode)&&(l=ie.call(a,l,!0)),l}let m=De?n.outerHTML:n.innerHTML;return De&&he["!doctype"]&&n.ownerDocument&&n.ownerDocument.doctype&&n.ownerDocument.doctype.name&&E(j,n.ownerDocument.doctype.name)&&(m="\n"+m),we&&u([le,ce,se],(e=>{m=g(m,e," ")})),Q&&Ce?Q.createHTML(m):m},o.setConfig=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};it(e),Le=!0},o.clearConfig=function(){nt=null,Le=!1},o.isValidAttribute=function(e,t,n){nt||it({});const o=tt(e),r=tt(t);return At(o,r,n)},o.addHook=function(e,t){"function"==typeof t&&(ae[e]=ae[e]||[],f(ae[e],t))},o.removeHook=function(e){if(ae[e])return m(ae[e])},o.removeHooks=function(e){ae[e]&&(ae[e]=[])},o.removeAllHooks=function(){ae={}},o}();return V})); +//# sourceMappingURL=purify.min.js.map diff --git a/src/ui/static/js/utils/purify/purify.min.js.map b/src/ui/static/js/utils/purify/purify.min.js.map new file mode 100644 index 000000000..c0e565f5b --- /dev/null +++ b/src/ui/static/js/utils/purify/purify.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"purify.min.js","sources":["src/utils.js","src/tags.js","src/attrs.js","src/regexp.js","src/purify.js"],"sourcesContent":["const {\n entries,\n setPrototypeOf,\n isFrozen,\n getPrototypeOf,\n getOwnPropertyDescriptor,\n} = Object;\n\nlet { freeze, seal, create } = Object; // eslint-disable-line import/no-mutable-exports\nlet { apply, construct } = typeof Reflect !== 'undefined' && Reflect;\n\nif (!freeze) {\n freeze = function (x) {\n return x;\n };\n}\n\nif (!seal) {\n seal = function (x) {\n return x;\n };\n}\n\nif (!apply) {\n apply = function (fun, thisValue, args) {\n return fun.apply(thisValue, args);\n };\n}\n\nif (!construct) {\n construct = function (Func, args) {\n return new Func(...args);\n };\n}\n\nconst arrayForEach = unapply(Array.prototype.forEach);\nconst arrayIndexOf = unapply(Array.prototype.indexOf);\nconst arrayPop = unapply(Array.prototype.pop);\nconst arrayPush = unapply(Array.prototype.push);\nconst arraySlice = unapply(Array.prototype.slice);\n\nconst stringToLowerCase = unapply(String.prototype.toLowerCase);\nconst stringToString = unapply(String.prototype.toString);\nconst stringMatch = unapply(String.prototype.match);\nconst stringReplace = unapply(String.prototype.replace);\nconst stringIndexOf = unapply(String.prototype.indexOf);\nconst stringTrim = unapply(String.prototype.trim);\n\nconst regExpTest = unapply(RegExp.prototype.test);\n\nconst typeErrorCreate = unconstruct(TypeError);\n\n/**\n * Creates a new function that calls the given function with a specified thisArg and arguments.\n *\n * @param {Function} func - The function to be wrapped and called.\n * @returns {Function} A new function that calls the given function with a specified thisArg and arguments.\n */\nfunction unapply(func) {\n return (thisArg, ...args) => apply(func, thisArg, args);\n}\n\n/**\n * Creates a new function that constructs an instance of the given constructor function with the provided arguments.\n *\n * @param {Function} func - The constructor function to be wrapped and called.\n * @returns {Function} A new function that constructs an instance of the given constructor function with the provided arguments.\n */\nfunction unconstruct(func) {\n return (...args) => construct(func, args);\n}\n\n/**\n * Add properties to a lookup table\n *\n * @param {Object} set - The set to which elements will be added.\n * @param {Array} array - The array containing elements to be added to the set.\n * @param {Function} transformCaseFunc - An optional function to transform the case of each element before adding to the set.\n * @returns {Object} The modified set with added elements.\n */\nfunction addToSet(set, array, transformCaseFunc = stringToLowerCase) {\n if (setPrototypeOf) {\n // Make 'in' and truthy checks like Boolean(set.constructor)\n // independent of any properties defined on Object.prototype.\n // Prevent prototype setters from intercepting set as a this value.\n setPrototypeOf(set, null);\n }\n\n let l = array.length;\n while (l--) {\n let element = array[l];\n if (typeof element === 'string') {\n const lcElement = transformCaseFunc(element);\n if (lcElement !== element) {\n // Config presets (e.g. tags.js, attrs.js) are immutable.\n if (!isFrozen(array)) {\n array[l] = lcElement;\n }\n\n element = lcElement;\n }\n }\n\n set[element] = true;\n }\n\n return set;\n}\n\n/**\n * Shallow clone an object\n *\n * @param {Object} object - The object to be cloned.\n * @returns {Object} A new object that copies the original.\n */\nexport function clone(object) {\n const newObject = create(null);\n\n for (const [property, value] of entries(object)) {\n if (getOwnPropertyDescriptor(object, property) !== undefined) {\n newObject[property] = value;\n }\n }\n\n return newObject;\n}\n\n/**\n * This method automatically checks if the prop is function or getter and behaves accordingly.\n *\n * @param {Object} object - The object to look up the getter function in its prototype chain.\n * @param {String} prop - The property name for which to find the getter function.\n * @returns {Function} The getter function found in the prototype chain or a fallback function.\n */\nfunction lookupGetter(object, prop) {\n while (object !== null) {\n const desc = getOwnPropertyDescriptor(object, prop);\n\n if (desc) {\n if (desc.get) {\n return unapply(desc.get);\n }\n\n if (typeof desc.value === 'function') {\n return unapply(desc.value);\n }\n }\n\n object = getPrototypeOf(object);\n }\n\n function fallbackValue(element) {\n console.warn('fallback value for', element);\n return null;\n }\n\n return fallbackValue;\n}\n\nexport {\n // Array\n arrayForEach,\n arrayIndexOf,\n arrayPop,\n arrayPush,\n arraySlice,\n // Object\n entries,\n freeze,\n getPrototypeOf,\n getOwnPropertyDescriptor,\n isFrozen,\n setPrototypeOf,\n seal,\n create,\n // RegExp\n regExpTest,\n // String\n stringIndexOf,\n stringMatch,\n stringReplace,\n stringToLowerCase,\n stringToString,\n stringTrim,\n // Errors\n typeErrorCreate,\n // Other\n lookupGetter,\n addToSet,\n // Reflect\n unapply,\n unconstruct,\n};\n","import { freeze } from './utils.js';\n\nexport const html = freeze([\n 'a',\n 'abbr',\n 'acronym',\n 'address',\n 'area',\n 'article',\n 'aside',\n 'audio',\n 'b',\n 'bdi',\n 'bdo',\n 'big',\n 'blink',\n 'blockquote',\n 'body',\n 'br',\n 'button',\n 'canvas',\n 'caption',\n 'center',\n 'cite',\n 'code',\n 'col',\n 'colgroup',\n 'content',\n 'data',\n 'datalist',\n 'dd',\n 'decorator',\n 'del',\n 'details',\n 'dfn',\n 'dialog',\n 'dir',\n 'div',\n 'dl',\n 'dt',\n 'element',\n 'em',\n 'fieldset',\n 'figcaption',\n 'figure',\n 'font',\n 'footer',\n 'form',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'head',\n 'header',\n 'hgroup',\n 'hr',\n 'html',\n 'i',\n 'img',\n 'input',\n 'ins',\n 'kbd',\n 'label',\n 'legend',\n 'li',\n 'main',\n 'map',\n 'mark',\n 'marquee',\n 'menu',\n 'menuitem',\n 'meter',\n 'nav',\n 'nobr',\n 'ol',\n 'optgroup',\n 'option',\n 'output',\n 'p',\n 'picture',\n 'pre',\n 'progress',\n 'q',\n 'rp',\n 'rt',\n 'ruby',\n 's',\n 'samp',\n 'section',\n 'select',\n 'shadow',\n 'small',\n 'source',\n 'spacer',\n 'span',\n 'strike',\n 'strong',\n 'style',\n 'sub',\n 'summary',\n 'sup',\n 'table',\n 'tbody',\n 'td',\n 'template',\n 'textarea',\n 'tfoot',\n 'th',\n 'thead',\n 'time',\n 'tr',\n 'track',\n 'tt',\n 'u',\n 'ul',\n 'var',\n 'video',\n 'wbr',\n]);\n\n// SVG\nexport const svg = freeze([\n 'svg',\n 'a',\n 'altglyph',\n 'altglyphdef',\n 'altglyphitem',\n 'animatecolor',\n 'animatemotion',\n 'animatetransform',\n 'circle',\n 'clippath',\n 'defs',\n 'desc',\n 'ellipse',\n 'filter',\n 'font',\n 'g',\n 'glyph',\n 'glyphref',\n 'hkern',\n 'image',\n 'line',\n 'lineargradient',\n 'marker',\n 'mask',\n 'metadata',\n 'mpath',\n 'path',\n 'pattern',\n 'polygon',\n 'polyline',\n 'radialgradient',\n 'rect',\n 'stop',\n 'style',\n 'switch',\n 'symbol',\n 'text',\n 'textpath',\n 'title',\n 'tref',\n 'tspan',\n 'view',\n 'vkern',\n]);\n\nexport const svgFilters = freeze([\n 'feBlend',\n 'feColorMatrix',\n 'feComponentTransfer',\n 'feComposite',\n 'feConvolveMatrix',\n 'feDiffuseLighting',\n 'feDisplacementMap',\n 'feDistantLight',\n 'feDropShadow',\n 'feFlood',\n 'feFuncA',\n 'feFuncB',\n 'feFuncG',\n 'feFuncR',\n 'feGaussianBlur',\n 'feImage',\n 'feMerge',\n 'feMergeNode',\n 'feMorphology',\n 'feOffset',\n 'fePointLight',\n 'feSpecularLighting',\n 'feSpotLight',\n 'feTile',\n 'feTurbulence',\n]);\n\n// List of SVG elements that are disallowed by default.\n// We still need to know them so that we can do namespace\n// checks properly in case one wants to add them to\n// allow-list.\nexport const svgDisallowed = freeze([\n 'animate',\n 'color-profile',\n 'cursor',\n 'discard',\n 'font-face',\n 'font-face-format',\n 'font-face-name',\n 'font-face-src',\n 'font-face-uri',\n 'foreignobject',\n 'hatch',\n 'hatchpath',\n 'mesh',\n 'meshgradient',\n 'meshpatch',\n 'meshrow',\n 'missing-glyph',\n 'script',\n 'set',\n 'solidcolor',\n 'unknown',\n 'use',\n]);\n\nexport const mathMl = freeze([\n 'math',\n 'menclose',\n 'merror',\n 'mfenced',\n 'mfrac',\n 'mglyph',\n 'mi',\n 'mlabeledtr',\n 'mmultiscripts',\n 'mn',\n 'mo',\n 'mover',\n 'mpadded',\n 'mphantom',\n 'mroot',\n 'mrow',\n 'ms',\n 'mspace',\n 'msqrt',\n 'mstyle',\n 'msub',\n 'msup',\n 'msubsup',\n 'mtable',\n 'mtd',\n 'mtext',\n 'mtr',\n 'munder',\n 'munderover',\n 'mprescripts',\n]);\n\n// Similarly to SVG, we want to know all MathML elements,\n// even those that we disallow by default.\nexport const mathMlDisallowed = freeze([\n 'maction',\n 'maligngroup',\n 'malignmark',\n 'mlongdiv',\n 'mscarries',\n 'mscarry',\n 'msgroup',\n 'mstack',\n 'msline',\n 'msrow',\n 'semantics',\n 'annotation',\n 'annotation-xml',\n 'mprescripts',\n 'none',\n]);\n\nexport const text = freeze(['#text']);\n","import { freeze } from './utils.js';\n\nexport const html = freeze([\n 'accept',\n 'action',\n 'align',\n 'alt',\n 'autocapitalize',\n 'autocomplete',\n 'autopictureinpicture',\n 'autoplay',\n 'background',\n 'bgcolor',\n 'border',\n 'capture',\n 'cellpadding',\n 'cellspacing',\n 'checked',\n 'cite',\n 'class',\n 'clear',\n 'color',\n 'cols',\n 'colspan',\n 'controls',\n 'controlslist',\n 'coords',\n 'crossorigin',\n 'datetime',\n 'decoding',\n 'default',\n 'dir',\n 'disabled',\n 'disablepictureinpicture',\n 'disableremoteplayback',\n 'download',\n 'draggable',\n 'enctype',\n 'enterkeyhint',\n 'face',\n 'for',\n 'headers',\n 'height',\n 'hidden',\n 'high',\n 'href',\n 'hreflang',\n 'id',\n 'inputmode',\n 'integrity',\n 'ismap',\n 'kind',\n 'label',\n 'lang',\n 'list',\n 'loading',\n 'loop',\n 'low',\n 'max',\n 'maxlength',\n 'media',\n 'method',\n 'min',\n 'minlength',\n 'multiple',\n 'muted',\n 'name',\n 'nonce',\n 'noshade',\n 'novalidate',\n 'nowrap',\n 'open',\n 'optimum',\n 'pattern',\n 'placeholder',\n 'playsinline',\n 'poster',\n 'preload',\n 'pubdate',\n 'radiogroup',\n 'readonly',\n 'rel',\n 'required',\n 'rev',\n 'reversed',\n 'role',\n 'rows',\n 'rowspan',\n 'spellcheck',\n 'scope',\n 'selected',\n 'shape',\n 'size',\n 'sizes',\n 'span',\n 'srclang',\n 'start',\n 'src',\n 'srcset',\n 'step',\n 'style',\n 'summary',\n 'tabindex',\n 'title',\n 'translate',\n 'type',\n 'usemap',\n 'valign',\n 'value',\n 'width',\n 'xmlns',\n 'slot',\n]);\n\nexport const svg = freeze([\n 'accent-height',\n 'accumulate',\n 'additive',\n 'alignment-baseline',\n 'ascent',\n 'attributename',\n 'attributetype',\n 'azimuth',\n 'basefrequency',\n 'baseline-shift',\n 'begin',\n 'bias',\n 'by',\n 'class',\n 'clip',\n 'clippathunits',\n 'clip-path',\n 'clip-rule',\n 'color',\n 'color-interpolation',\n 'color-interpolation-filters',\n 'color-profile',\n 'color-rendering',\n 'cx',\n 'cy',\n 'd',\n 'dx',\n 'dy',\n 'diffuseconstant',\n 'direction',\n 'display',\n 'divisor',\n 'dur',\n 'edgemode',\n 'elevation',\n 'end',\n 'fill',\n 'fill-opacity',\n 'fill-rule',\n 'filter',\n 'filterunits',\n 'flood-color',\n 'flood-opacity',\n 'font-family',\n 'font-size',\n 'font-size-adjust',\n 'font-stretch',\n 'font-style',\n 'font-variant',\n 'font-weight',\n 'fx',\n 'fy',\n 'g1',\n 'g2',\n 'glyph-name',\n 'glyphref',\n 'gradientunits',\n 'gradienttransform',\n 'height',\n 'href',\n 'id',\n 'image-rendering',\n 'in',\n 'in2',\n 'k',\n 'k1',\n 'k2',\n 'k3',\n 'k4',\n 'kerning',\n 'keypoints',\n 'keysplines',\n 'keytimes',\n 'lang',\n 'lengthadjust',\n 'letter-spacing',\n 'kernelmatrix',\n 'kernelunitlength',\n 'lighting-color',\n 'local',\n 'marker-end',\n 'marker-mid',\n 'marker-start',\n 'markerheight',\n 'markerunits',\n 'markerwidth',\n 'maskcontentunits',\n 'maskunits',\n 'max',\n 'mask',\n 'media',\n 'method',\n 'mode',\n 'min',\n 'name',\n 'numoctaves',\n 'offset',\n 'operator',\n 'opacity',\n 'order',\n 'orient',\n 'orientation',\n 'origin',\n 'overflow',\n 'paint-order',\n 'path',\n 'pathlength',\n 'patterncontentunits',\n 'patterntransform',\n 'patternunits',\n 'points',\n 'preservealpha',\n 'preserveaspectratio',\n 'primitiveunits',\n 'r',\n 'rx',\n 'ry',\n 'radius',\n 'refx',\n 'refy',\n 'repeatcount',\n 'repeatdur',\n 'restart',\n 'result',\n 'rotate',\n 'scale',\n 'seed',\n 'shape-rendering',\n 'specularconstant',\n 'specularexponent',\n 'spreadmethod',\n 'startoffset',\n 'stddeviation',\n 'stitchtiles',\n 'stop-color',\n 'stop-opacity',\n 'stroke-dasharray',\n 'stroke-dashoffset',\n 'stroke-linecap',\n 'stroke-linejoin',\n 'stroke-miterlimit',\n 'stroke-opacity',\n 'stroke',\n 'stroke-width',\n 'style',\n 'surfacescale',\n 'systemlanguage',\n 'tabindex',\n 'targetx',\n 'targety',\n 'transform',\n 'transform-origin',\n 'text-anchor',\n 'text-decoration',\n 'text-rendering',\n 'textlength',\n 'type',\n 'u1',\n 'u2',\n 'unicode',\n 'values',\n 'viewbox',\n 'visibility',\n 'version',\n 'vert-adv-y',\n 'vert-origin-x',\n 'vert-origin-y',\n 'width',\n 'word-spacing',\n 'wrap',\n 'writing-mode',\n 'xchannelselector',\n 'ychannelselector',\n 'x',\n 'x1',\n 'x2',\n 'xmlns',\n 'y',\n 'y1',\n 'y2',\n 'z',\n 'zoomandpan',\n]);\n\nexport const mathMl = freeze([\n 'accent',\n 'accentunder',\n 'align',\n 'bevelled',\n 'close',\n 'columnsalign',\n 'columnlines',\n 'columnspan',\n 'denomalign',\n 'depth',\n 'dir',\n 'display',\n 'displaystyle',\n 'encoding',\n 'fence',\n 'frame',\n 'height',\n 'href',\n 'id',\n 'largeop',\n 'length',\n 'linethickness',\n 'lspace',\n 'lquote',\n 'mathbackground',\n 'mathcolor',\n 'mathsize',\n 'mathvariant',\n 'maxsize',\n 'minsize',\n 'movablelimits',\n 'notation',\n 'numalign',\n 'open',\n 'rowalign',\n 'rowlines',\n 'rowspacing',\n 'rowspan',\n 'rspace',\n 'rquote',\n 'scriptlevel',\n 'scriptminsize',\n 'scriptsizemultiplier',\n 'selection',\n 'separator',\n 'separators',\n 'stretchy',\n 'subscriptshift',\n 'supscriptshift',\n 'symmetric',\n 'voffset',\n 'width',\n 'xmlns',\n]);\n\nexport const xml = freeze([\n 'xlink:href',\n 'xml:id',\n 'xlink:title',\n 'xml:space',\n 'xmlns:xlink',\n]);\n","import { seal } from './utils.js';\n\n// eslint-disable-next-line unicorn/better-regex\nexport const MUSTACHE_EXPR = seal(/\\{\\{[\\w\\W]*|[\\w\\W]*\\}\\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode\nexport const ERB_EXPR = seal(/<%[\\w\\W]*|[\\w\\W]*%>/gm);\nexport const TMPLIT_EXPR = seal(/\\${[\\w\\W]*}/gm);\nexport const DATA_ATTR = seal(/^data-[\\-\\w.\\u00B7-\\uFFFF]/); // eslint-disable-line no-useless-escape\nexport const ARIA_ATTR = seal(/^aria-[\\-\\w]+$/); // eslint-disable-line no-useless-escape\nexport const IS_ALLOWED_URI = seal(\n /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\\-]+(?:[^a-z+.\\-:]|$))/i // eslint-disable-line no-useless-escape\n);\nexport const IS_SCRIPT_OR_DATA = seal(/^(?:\\w+script|data):/i);\nexport const ATTR_WHITESPACE = seal(\n /[\\u0000-\\u0020\\u00A0\\u1680\\u180E\\u2000-\\u2029\\u205F\\u3000]/g // eslint-disable-line no-control-regex\n);\nexport const DOCTYPE_NAME = seal(/^html$/i);\n","import * as TAGS from './tags.js';\nimport * as ATTRS from './attrs.js';\nimport * as EXPRESSIONS from './regexp.js';\nimport {\n addToSet,\n clone,\n entries,\n freeze,\n arrayForEach,\n arrayPop,\n arrayPush,\n stringMatch,\n stringReplace,\n stringToLowerCase,\n stringToString,\n stringIndexOf,\n stringTrim,\n regExpTest,\n typeErrorCreate,\n lookupGetter,\n create,\n} from './utils.js';\n\nconst getGlobal = function () {\n return typeof window === 'undefined' ? null : window;\n};\n\n/**\n * Creates a no-op policy for internal use only.\n * Don't export this function outside this module!\n * @param {?TrustedTypePolicyFactory} trustedTypes The policy factory.\n * @param {HTMLScriptElement} purifyHostElement The Script element used to load DOMPurify (to determine policy name suffix).\n * @return {?TrustedTypePolicy} The policy created (or null, if Trusted Types\n * are not supported or creating the policy failed).\n */\nconst _createTrustedTypesPolicy = function (trustedTypes, purifyHostElement) {\n if (\n typeof trustedTypes !== 'object' ||\n typeof trustedTypes.createPolicy !== 'function'\n ) {\n return null;\n }\n\n // Allow the callers to control the unique policy name\n // by adding a data-tt-policy-suffix to the script element with the DOMPurify.\n // Policy creation with duplicate names throws in Trusted Types.\n let suffix = null;\n const ATTR_NAME = 'data-tt-policy-suffix';\n if (purifyHostElement && purifyHostElement.hasAttribute(ATTR_NAME)) {\n suffix = purifyHostElement.getAttribute(ATTR_NAME);\n }\n\n const policyName = 'dompurify' + (suffix ? '#' + suffix : '');\n\n try {\n return trustedTypes.createPolicy(policyName, {\n createHTML(html) {\n return html;\n },\n createScriptURL(scriptUrl) {\n return scriptUrl;\n },\n });\n } catch (_) {\n // Policy creation failed (most likely another DOMPurify script has\n // already run). Skip creating the policy, as this will only cause errors\n // if TT are enforced.\n console.warn(\n 'TrustedTypes policy ' + policyName + ' could not be created.'\n );\n return null;\n }\n};\n\nfunction createDOMPurify(window = getGlobal()) {\n const DOMPurify = (root) => createDOMPurify(root);\n\n /**\n * Version label, exposed for easier checks\n * if DOMPurify is up to date or not\n */\n DOMPurify.version = VERSION;\n\n /**\n * Array of elements that DOMPurify removed during sanitation.\n * Empty if nothing was removed.\n */\n DOMPurify.removed = [];\n\n if (!window || !window.document || window.document.nodeType !== 9) {\n // Not running in a browser, provide a factory function\n // so that you can pass your own Window\n DOMPurify.isSupported = false;\n\n return DOMPurify;\n }\n\n let { document } = window;\n\n const originalDocument = document;\n const currentScript = originalDocument.currentScript;\n const {\n DocumentFragment,\n HTMLTemplateElement,\n Node,\n Element,\n NodeFilter,\n NamedNodeMap = window.NamedNodeMap || window.MozNamedAttrMap,\n HTMLFormElement,\n DOMParser,\n trustedTypes,\n } = window;\n\n const ElementPrototype = Element.prototype;\n\n const cloneNode = lookupGetter(ElementPrototype, 'cloneNode');\n const getNextSibling = lookupGetter(ElementPrototype, 'nextSibling');\n const getChildNodes = lookupGetter(ElementPrototype, 'childNodes');\n const getParentNode = lookupGetter(ElementPrototype, 'parentNode');\n\n // As per issue #47, the web-components registry is inherited by a\n // new document created via createHTMLDocument. As per the spec\n // (http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries)\n // a new empty registry is used when creating a template contents owner\n // document, so we use that as our parent document to ensure nothing\n // is inherited.\n if (typeof HTMLTemplateElement === 'function') {\n const template = document.createElement('template');\n if (template.content && template.content.ownerDocument) {\n document = template.content.ownerDocument;\n }\n }\n\n let trustedTypesPolicy;\n let emptyHTML = '';\n\n const {\n implementation,\n createNodeIterator,\n createDocumentFragment,\n getElementsByTagName,\n } = document;\n const { importNode } = originalDocument;\n\n let hooks = {};\n\n /**\n * Expose whether this browser supports running the full DOMPurify.\n */\n DOMPurify.isSupported =\n typeof entries === 'function' &&\n typeof getParentNode === 'function' &&\n implementation &&\n implementation.createHTMLDocument !== undefined;\n\n const {\n MUSTACHE_EXPR,\n ERB_EXPR,\n TMPLIT_EXPR,\n DATA_ATTR,\n ARIA_ATTR,\n IS_SCRIPT_OR_DATA,\n ATTR_WHITESPACE,\n } = EXPRESSIONS;\n\n let { IS_ALLOWED_URI } = EXPRESSIONS;\n\n /**\n * We consider the elements and attributes below to be safe. Ideally\n * don't add any new ones but feel free to remove unwanted ones.\n */\n\n /* allowed element names */\n let ALLOWED_TAGS = null;\n const DEFAULT_ALLOWED_TAGS = addToSet({}, [\n ...TAGS.html,\n ...TAGS.svg,\n ...TAGS.svgFilters,\n ...TAGS.mathMl,\n ...TAGS.text,\n ]);\n\n /* Allowed attribute names */\n let ALLOWED_ATTR = null;\n const DEFAULT_ALLOWED_ATTR = addToSet({}, [\n ...ATTRS.html,\n ...ATTRS.svg,\n ...ATTRS.mathMl,\n ...ATTRS.xml,\n ]);\n\n /*\n * Configure how DOMPUrify should handle custom elements and their attributes as well as customized built-in elements.\n * @property {RegExp|Function|null} tagNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any custom elements)\n * @property {RegExp|Function|null} attributeNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any attributes not on the allow list)\n * @property {boolean} allowCustomizedBuiltInElements allow custom elements derived from built-ins if they pass CUSTOM_ELEMENT_HANDLING.tagNameCheck. Default: `false`.\n */\n let CUSTOM_ELEMENT_HANDLING = Object.seal(\n create(null, {\n tagNameCheck: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: null,\n },\n attributeNameCheck: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: null,\n },\n allowCustomizedBuiltInElements: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: false,\n },\n })\n );\n\n /* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */\n let FORBID_TAGS = null;\n\n /* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */\n let FORBID_ATTR = null;\n\n /* Decide if ARIA attributes are okay */\n let ALLOW_ARIA_ATTR = true;\n\n /* Decide if custom data attributes are okay */\n let ALLOW_DATA_ATTR = true;\n\n /* Decide if unknown protocols are okay */\n let ALLOW_UNKNOWN_PROTOCOLS = false;\n\n /* Decide if self-closing tags in attributes are allowed.\n * Usually removed due to a mXSS issue in jQuery 3.0 */\n let ALLOW_SELF_CLOSE_IN_ATTR = true;\n\n /* Output should be safe for common template engines.\n * This means, DOMPurify removes data attributes, mustaches and ERB\n */\n let SAFE_FOR_TEMPLATES = false;\n\n /* Decide if document with ... should be returned */\n let WHOLE_DOCUMENT = false;\n\n /* Track whether config is already set on this instance of DOMPurify. */\n let SET_CONFIG = false;\n\n /* Decide if all elements (e.g. style, script) must be children of\n * document.body. By default, browsers might move them to document.head */\n let FORCE_BODY = false;\n\n /* Decide if a DOM `HTMLBodyElement` should be returned, instead of a html\n * string (or a TrustedHTML object if Trusted Types are supported).\n * If `WHOLE_DOCUMENT` is enabled a `HTMLHtmlElement` will be returned instead\n */\n let RETURN_DOM = false;\n\n /* Decide if a DOM `DocumentFragment` should be returned, instead of a html\n * string (or a TrustedHTML object if Trusted Types are supported) */\n let RETURN_DOM_FRAGMENT = false;\n\n /* Try to return a Trusted Type object instead of a string, return a string in\n * case Trusted Types are not supported */\n let RETURN_TRUSTED_TYPE = false;\n\n /* Output should be free from DOM clobbering attacks?\n * This sanitizes markups named with colliding, clobberable built-in DOM APIs.\n */\n let SANITIZE_DOM = true;\n\n /* Achieve full DOM Clobbering protection by isolating the namespace of named\n * properties and JS variables, mitigating attacks that abuse the HTML/DOM spec rules.\n *\n * HTML/DOM spec rules that enable DOM Clobbering:\n * - Named Access on Window (§7.3.3)\n * - DOM Tree Accessors (§3.1.5)\n * - Form Element Parent-Child Relations (§4.10.3)\n * - Iframe srcdoc / Nested WindowProxies (§4.8.5)\n * - HTMLCollection (§4.2.10.2)\n *\n * Namespace isolation is implemented by prefixing `id` and `name` attributes\n * with a constant string, i.e., `user-content-`\n */\n let SANITIZE_NAMED_PROPS = false;\n const SANITIZE_NAMED_PROPS_PREFIX = 'user-content-';\n\n /* Keep element content when removing element? */\n let KEEP_CONTENT = true;\n\n /* If a `Node` is passed to sanitize(), then performs sanitization in-place instead\n * of importing it into a new Document and returning a sanitized copy */\n let IN_PLACE = false;\n\n /* Allow usage of profiles like html, svg and mathMl */\n let USE_PROFILES = {};\n\n /* Tags to ignore content of when KEEP_CONTENT is true */\n let FORBID_CONTENTS = null;\n const DEFAULT_FORBID_CONTENTS = addToSet({}, [\n 'annotation-xml',\n 'audio',\n 'colgroup',\n 'desc',\n 'foreignobject',\n 'head',\n 'iframe',\n 'math',\n 'mi',\n 'mn',\n 'mo',\n 'ms',\n 'mtext',\n 'noembed',\n 'noframes',\n 'noscript',\n 'plaintext',\n 'script',\n 'style',\n 'svg',\n 'template',\n 'thead',\n 'title',\n 'video',\n 'xmp',\n ]);\n\n /* Tags that are safe for data: URIs */\n let DATA_URI_TAGS = null;\n const DEFAULT_DATA_URI_TAGS = addToSet({}, [\n 'audio',\n 'video',\n 'img',\n 'source',\n 'image',\n 'track',\n ]);\n\n /* Attributes safe for values like \"javascript:\" */\n let URI_SAFE_ATTRIBUTES = null;\n const DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, [\n 'alt',\n 'class',\n 'for',\n 'id',\n 'label',\n 'name',\n 'pattern',\n 'placeholder',\n 'role',\n 'summary',\n 'title',\n 'value',\n 'style',\n 'xmlns',\n ]);\n\n const MATHML_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';\n const SVG_NAMESPACE = 'http://www.w3.org/2000/svg';\n const HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';\n /* Document namespace */\n let NAMESPACE = HTML_NAMESPACE;\n let IS_EMPTY_INPUT = false;\n\n /* Allowed XHTML+XML namespaces */\n let ALLOWED_NAMESPACES = null;\n const DEFAULT_ALLOWED_NAMESPACES = addToSet(\n {},\n [MATHML_NAMESPACE, SVG_NAMESPACE, HTML_NAMESPACE],\n stringToString\n );\n\n /* Parsing of strict XHTML documents */\n let PARSER_MEDIA_TYPE = null;\n const SUPPORTED_PARSER_MEDIA_TYPES = ['application/xhtml+xml', 'text/html'];\n const DEFAULT_PARSER_MEDIA_TYPE = 'text/html';\n let transformCaseFunc = null;\n\n /* Keep a reference to config to pass to hooks */\n let CONFIG = null;\n\n /* Ideally, do not touch anything below this line */\n /* ______________________________________________ */\n\n const formElement = document.createElement('form');\n\n const isRegexOrFunction = function (testValue) {\n return testValue instanceof RegExp || testValue instanceof Function;\n };\n\n /**\n * _parseConfig\n *\n * @param {Object} cfg optional config literal\n */\n // eslint-disable-next-line complexity\n const _parseConfig = function (cfg = {}) {\n if (CONFIG && CONFIG === cfg) {\n return;\n }\n\n /* Shield configuration object from tampering */\n if (!cfg || typeof cfg !== 'object') {\n cfg = {};\n }\n\n /* Shield configuration object from prototype pollution */\n cfg = clone(cfg);\n\n PARSER_MEDIA_TYPE =\n // eslint-disable-next-line unicorn/prefer-includes\n SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1\n ? (PARSER_MEDIA_TYPE = DEFAULT_PARSER_MEDIA_TYPE)\n : (PARSER_MEDIA_TYPE = cfg.PARSER_MEDIA_TYPE);\n\n // HTML tags and attributes are not case-sensitive, converting to lowercase. Keeping XHTML as is.\n transformCaseFunc =\n PARSER_MEDIA_TYPE === 'application/xhtml+xml'\n ? stringToString\n : stringToLowerCase;\n\n /* Set configuration parameters */\n ALLOWED_TAGS =\n 'ALLOWED_TAGS' in cfg\n ? addToSet({}, cfg.ALLOWED_TAGS, transformCaseFunc)\n : DEFAULT_ALLOWED_TAGS;\n ALLOWED_ATTR =\n 'ALLOWED_ATTR' in cfg\n ? addToSet({}, cfg.ALLOWED_ATTR, transformCaseFunc)\n : DEFAULT_ALLOWED_ATTR;\n ALLOWED_NAMESPACES =\n 'ALLOWED_NAMESPACES' in cfg\n ? addToSet({}, cfg.ALLOWED_NAMESPACES, stringToString)\n : DEFAULT_ALLOWED_NAMESPACES;\n URI_SAFE_ATTRIBUTES =\n 'ADD_URI_SAFE_ATTR' in cfg\n ? addToSet(\n clone(DEFAULT_URI_SAFE_ATTRIBUTES), // eslint-disable-line indent\n cfg.ADD_URI_SAFE_ATTR, // eslint-disable-line indent\n transformCaseFunc // eslint-disable-line indent\n ) // eslint-disable-line indent\n : DEFAULT_URI_SAFE_ATTRIBUTES;\n DATA_URI_TAGS =\n 'ADD_DATA_URI_TAGS' in cfg\n ? addToSet(\n clone(DEFAULT_DATA_URI_TAGS), // eslint-disable-line indent\n cfg.ADD_DATA_URI_TAGS, // eslint-disable-line indent\n transformCaseFunc // eslint-disable-line indent\n ) // eslint-disable-line indent\n : DEFAULT_DATA_URI_TAGS;\n FORBID_CONTENTS =\n 'FORBID_CONTENTS' in cfg\n ? addToSet({}, cfg.FORBID_CONTENTS, transformCaseFunc)\n : DEFAULT_FORBID_CONTENTS;\n FORBID_TAGS =\n 'FORBID_TAGS' in cfg\n ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc)\n : {};\n FORBID_ATTR =\n 'FORBID_ATTR' in cfg\n ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc)\n : {};\n USE_PROFILES = 'USE_PROFILES' in cfg ? cfg.USE_PROFILES : false;\n ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true\n ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true\n ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false\n ALLOW_SELF_CLOSE_IN_ATTR = cfg.ALLOW_SELF_CLOSE_IN_ATTR !== false; // Default true\n SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; // Default false\n WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false\n RETURN_DOM = cfg.RETURN_DOM || false; // Default false\n RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false\n RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; // Default false\n FORCE_BODY = cfg.FORCE_BODY || false; // Default false\n SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true\n SANITIZE_NAMED_PROPS = cfg.SANITIZE_NAMED_PROPS || false; // Default false\n KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true\n IN_PLACE = cfg.IN_PLACE || false; // Default false\n IS_ALLOWED_URI = cfg.ALLOWED_URI_REGEXP || EXPRESSIONS.IS_ALLOWED_URI;\n NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE;\n CUSTOM_ELEMENT_HANDLING = cfg.CUSTOM_ELEMENT_HANDLING || {};\n if (\n cfg.CUSTOM_ELEMENT_HANDLING &&\n isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck)\n ) {\n CUSTOM_ELEMENT_HANDLING.tagNameCheck =\n cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck;\n }\n\n if (\n cfg.CUSTOM_ELEMENT_HANDLING &&\n isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)\n ) {\n CUSTOM_ELEMENT_HANDLING.attributeNameCheck =\n cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck;\n }\n\n if (\n cfg.CUSTOM_ELEMENT_HANDLING &&\n typeof cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements ===\n 'boolean'\n ) {\n CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements =\n cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements;\n }\n\n if (SAFE_FOR_TEMPLATES) {\n ALLOW_DATA_ATTR = false;\n }\n\n if (RETURN_DOM_FRAGMENT) {\n RETURN_DOM = true;\n }\n\n /* Parse profile info */\n if (USE_PROFILES) {\n ALLOWED_TAGS = addToSet({}, [...TAGS.text]);\n ALLOWED_ATTR = [];\n if (USE_PROFILES.html === true) {\n addToSet(ALLOWED_TAGS, TAGS.html);\n addToSet(ALLOWED_ATTR, ATTRS.html);\n }\n\n if (USE_PROFILES.svg === true) {\n addToSet(ALLOWED_TAGS, TAGS.svg);\n addToSet(ALLOWED_ATTR, ATTRS.svg);\n addToSet(ALLOWED_ATTR, ATTRS.xml);\n }\n\n if (USE_PROFILES.svgFilters === true) {\n addToSet(ALLOWED_TAGS, TAGS.svgFilters);\n addToSet(ALLOWED_ATTR, ATTRS.svg);\n addToSet(ALLOWED_ATTR, ATTRS.xml);\n }\n\n if (USE_PROFILES.mathMl === true) {\n addToSet(ALLOWED_TAGS, TAGS.mathMl);\n addToSet(ALLOWED_ATTR, ATTRS.mathMl);\n addToSet(ALLOWED_ATTR, ATTRS.xml);\n }\n }\n\n /* Merge configuration parameters */\n if (cfg.ADD_TAGS) {\n if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {\n ALLOWED_TAGS = clone(ALLOWED_TAGS);\n }\n\n addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc);\n }\n\n if (cfg.ADD_ATTR) {\n if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) {\n ALLOWED_ATTR = clone(ALLOWED_ATTR);\n }\n\n addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc);\n }\n\n if (cfg.ADD_URI_SAFE_ATTR) {\n addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc);\n }\n\n if (cfg.FORBID_CONTENTS) {\n if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {\n FORBID_CONTENTS = clone(FORBID_CONTENTS);\n }\n\n addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc);\n }\n\n /* Add #text in case KEEP_CONTENT is set to true */\n if (KEEP_CONTENT) {\n ALLOWED_TAGS['#text'] = true;\n }\n\n /* Add html, head and body to ALLOWED_TAGS in case WHOLE_DOCUMENT is true */\n if (WHOLE_DOCUMENT) {\n addToSet(ALLOWED_TAGS, ['html', 'head', 'body']);\n }\n\n /* Add tbody to ALLOWED_TAGS in case tables are permitted, see #286, #365 */\n if (ALLOWED_TAGS.table) {\n addToSet(ALLOWED_TAGS, ['tbody']);\n delete FORBID_TAGS.tbody;\n }\n\n if (cfg.TRUSTED_TYPES_POLICY) {\n if (typeof cfg.TRUSTED_TYPES_POLICY.createHTML !== 'function') {\n throw typeErrorCreate(\n 'TRUSTED_TYPES_POLICY configuration option must provide a \"createHTML\" hook.'\n );\n }\n\n if (typeof cfg.TRUSTED_TYPES_POLICY.createScriptURL !== 'function') {\n throw typeErrorCreate(\n 'TRUSTED_TYPES_POLICY configuration option must provide a \"createScriptURL\" hook.'\n );\n }\n\n // Overwrite existing TrustedTypes policy.\n trustedTypesPolicy = cfg.TRUSTED_TYPES_POLICY;\n\n // Sign local variables required by `sanitize`.\n emptyHTML = trustedTypesPolicy.createHTML('');\n } else {\n // Uninitialized policy, attempt to initialize the internal dompurify policy.\n if (trustedTypesPolicy === undefined) {\n trustedTypesPolicy = _createTrustedTypesPolicy(\n trustedTypes,\n currentScript\n );\n }\n\n // If creating the internal policy succeeded sign internal variables.\n if (trustedTypesPolicy !== null && typeof emptyHTML === 'string') {\n emptyHTML = trustedTypesPolicy.createHTML('');\n }\n }\n\n // Prevent further manipulation of configuration.\n // Not available in IE8, Safari 5, etc.\n if (freeze) {\n freeze(cfg);\n }\n\n CONFIG = cfg;\n };\n\n const MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, [\n 'mi',\n 'mo',\n 'mn',\n 'ms',\n 'mtext',\n ]);\n\n const HTML_INTEGRATION_POINTS = addToSet({}, [\n 'foreignobject',\n 'desc',\n 'title',\n 'annotation-xml',\n ]);\n\n // Certain elements are allowed in both SVG and HTML\n // namespace. We need to specify them explicitly\n // so that they don't get erroneously deleted from\n // HTML namespace.\n const COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, [\n 'title',\n 'style',\n 'font',\n 'a',\n 'script',\n ]);\n\n /* Keep track of all possible SVG and MathML tags\n * so that we can perform the namespace checks\n * correctly. */\n const ALL_SVG_TAGS = addToSet({}, TAGS.svg);\n addToSet(ALL_SVG_TAGS, TAGS.svgFilters);\n addToSet(ALL_SVG_TAGS, TAGS.svgDisallowed);\n\n const ALL_MATHML_TAGS = addToSet({}, TAGS.mathMl);\n addToSet(ALL_MATHML_TAGS, TAGS.mathMlDisallowed);\n\n /**\n * @param {Element} element a DOM element whose namespace is being checked\n * @returns {boolean} Return false if the element has a\n * namespace that a spec-compliant parser would never\n * return. Return true otherwise.\n */\n const _checkValidNamespace = function (element) {\n let parent = getParentNode(element);\n\n // In JSDOM, if we're inside shadow DOM, then parentNode\n // can be null. We just simulate parent in this case.\n if (!parent || !parent.tagName) {\n parent = {\n namespaceURI: NAMESPACE,\n tagName: 'template',\n };\n }\n\n const tagName = stringToLowerCase(element.tagName);\n const parentTagName = stringToLowerCase(parent.tagName);\n\n if (!ALLOWED_NAMESPACES[element.namespaceURI]) {\n return false;\n }\n\n if (element.namespaceURI === SVG_NAMESPACE) {\n // The only way to switch from HTML namespace to SVG\n // is via . If it happens via any other tag, then\n // it should be killed.\n if (parent.namespaceURI === HTML_NAMESPACE) {\n return tagName === 'svg';\n }\n\n // The only way to switch from MathML to SVG is via`\n // svg if parent is either or MathML\n // text integration points.\n if (parent.namespaceURI === MATHML_NAMESPACE) {\n return (\n tagName === 'svg' &&\n (parentTagName === 'annotation-xml' ||\n MATHML_TEXT_INTEGRATION_POINTS[parentTagName])\n );\n }\n\n // We only allow elements that are defined in SVG\n // spec. All others are disallowed in SVG namespace.\n return Boolean(ALL_SVG_TAGS[tagName]);\n }\n\n if (element.namespaceURI === MATHML_NAMESPACE) {\n // The only way to switch from HTML namespace to MathML\n // is via . If it happens via any other tag, then\n // it should be killed.\n if (parent.namespaceURI === HTML_NAMESPACE) {\n return tagName === 'math';\n }\n\n // The only way to switch from SVG to MathML is via\n // and HTML integration points\n if (parent.namespaceURI === SVG_NAMESPACE) {\n return tagName === 'math' && HTML_INTEGRATION_POINTS[parentTagName];\n }\n\n // We only allow elements that are defined in MathML\n // spec. All others are disallowed in MathML namespace.\n return Boolean(ALL_MATHML_TAGS[tagName]);\n }\n\n if (element.namespaceURI === HTML_NAMESPACE) {\n // The only way to switch from SVG to HTML is via\n // HTML integration points, and from MathML to HTML\n // is via MathML text integration points\n if (\n parent.namespaceURI === SVG_NAMESPACE &&\n !HTML_INTEGRATION_POINTS[parentTagName]\n ) {\n return false;\n }\n\n if (\n parent.namespaceURI === MATHML_NAMESPACE &&\n !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]\n ) {\n return false;\n }\n\n // We disallow tags that are specific for MathML\n // or SVG and should never appear in HTML namespace\n return (\n !ALL_MATHML_TAGS[tagName] &&\n (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName])\n );\n }\n\n // For XHTML and XML documents that support custom namespaces\n if (\n PARSER_MEDIA_TYPE === 'application/xhtml+xml' &&\n ALLOWED_NAMESPACES[element.namespaceURI]\n ) {\n return true;\n }\n\n // The code should never reach this place (this means\n // that the element somehow got namespace that is not\n // HTML, SVG, MathML or allowed via ALLOWED_NAMESPACES).\n // Return false just in case.\n return false;\n };\n\n /**\n * _forceRemove\n *\n * @param {Node} node a DOM node\n */\n const _forceRemove = function (node) {\n arrayPush(DOMPurify.removed, { element: node });\n try {\n // eslint-disable-next-line unicorn/prefer-dom-node-remove\n node.parentNode.removeChild(node);\n } catch (_) {\n node.remove();\n }\n };\n\n /**\n * _removeAttribute\n *\n * @param {String} name an Attribute name\n * @param {Node} node a DOM node\n */\n const _removeAttribute = function (name, node) {\n try {\n arrayPush(DOMPurify.removed, {\n attribute: node.getAttributeNode(name),\n from: node,\n });\n } catch (_) {\n arrayPush(DOMPurify.removed, {\n attribute: null,\n from: node,\n });\n }\n\n node.removeAttribute(name);\n\n // We void attribute values for unremovable \"is\"\" attributes\n if (name === 'is' && !ALLOWED_ATTR[name]) {\n if (RETURN_DOM || RETURN_DOM_FRAGMENT) {\n try {\n _forceRemove(node);\n } catch (_) {}\n } else {\n try {\n node.setAttribute(name, '');\n } catch (_) {}\n }\n }\n };\n\n /**\n * _initDocument\n *\n * @param {String} dirty a string of dirty markup\n * @return {Document} a DOM, filled with the dirty markup\n */\n const _initDocument = function (dirty) {\n /* Create a HTML document */\n let doc = null;\n let leadingWhitespace = null;\n\n if (FORCE_BODY) {\n dirty = '' + dirty;\n } else {\n /* If FORCE_BODY isn't used, leading whitespace needs to be preserved manually */\n const matches = stringMatch(dirty, /^[\\r\\n\\t ]+/);\n leadingWhitespace = matches && matches[0];\n }\n\n if (\n PARSER_MEDIA_TYPE === 'application/xhtml+xml' &&\n NAMESPACE === HTML_NAMESPACE\n ) {\n // Root of XHTML doc must contain xmlns declaration (see https://www.w3.org/TR/xhtml1/normative.html#strict)\n dirty =\n '' +\n dirty +\n '';\n }\n\n const dirtyPayload = trustedTypesPolicy\n ? trustedTypesPolicy.createHTML(dirty)\n : dirty;\n /*\n * Use the DOMParser API by default, fallback later if needs be\n * DOMParser not work for svg when has multiple root element.\n */\n if (NAMESPACE === HTML_NAMESPACE) {\n try {\n doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE);\n } catch (_) {}\n }\n\n /* Use createHTMLDocument in case DOMParser is not available */\n if (!doc || !doc.documentElement) {\n doc = implementation.createDocument(NAMESPACE, 'template', null);\n try {\n doc.documentElement.innerHTML = IS_EMPTY_INPUT\n ? emptyHTML\n : dirtyPayload;\n } catch (_) {\n // Syntax error if dirtyPayload is invalid xml\n }\n }\n\n const body = doc.body || doc.documentElement;\n\n if (dirty && leadingWhitespace) {\n body.insertBefore(\n document.createTextNode(leadingWhitespace),\n body.childNodes[0] || null\n );\n }\n\n /* Work on whole document or just its body */\n if (NAMESPACE === HTML_NAMESPACE) {\n return getElementsByTagName.call(\n doc,\n WHOLE_DOCUMENT ? 'html' : 'body'\n )[0];\n }\n\n return WHOLE_DOCUMENT ? doc.documentElement : body;\n };\n\n /**\n * Creates a NodeIterator object that you can use to traverse filtered lists of nodes or elements in a document.\n *\n * @param {Node} root The root element or node to start traversing on.\n * @return {NodeIterator} The created NodeIterator\n */\n const _createNodeIterator = function (root) {\n return createNodeIterator.call(\n root.ownerDocument || root,\n root,\n // eslint-disable-next-line no-bitwise\n NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT,\n null\n );\n };\n\n /**\n * _isClobbered\n *\n * @param {Node} elm element to check for clobbering attacks\n * @return {Boolean} true if clobbered, false if safe\n */\n const _isClobbered = function (elm) {\n return (\n elm instanceof HTMLFormElement &&\n (typeof elm.nodeName !== 'string' ||\n typeof elm.textContent !== 'string' ||\n typeof elm.removeChild !== 'function' ||\n !(elm.attributes instanceof NamedNodeMap) ||\n typeof elm.removeAttribute !== 'function' ||\n typeof elm.setAttribute !== 'function' ||\n typeof elm.namespaceURI !== 'string' ||\n typeof elm.insertBefore !== 'function' ||\n typeof elm.hasChildNodes !== 'function')\n );\n };\n\n /**\n * Checks whether the given object is a DOM node.\n *\n * @param {Node} object object to check whether it's a DOM node\n * @return {Boolean} true is object is a DOM node\n */\n const _isNode = function (object) {\n return typeof Node === 'function' && object instanceof Node;\n };\n\n /**\n * _executeHook\n * Execute user configurable hooks\n *\n * @param {String} entryPoint Name of the hook's entry point\n * @param {Node} currentNode node to work on with the hook\n * @param {Object} data additional hook parameters\n */\n const _executeHook = function (entryPoint, currentNode, data) {\n if (!hooks[entryPoint]) {\n return;\n }\n\n arrayForEach(hooks[entryPoint], (hook) => {\n hook.call(DOMPurify, currentNode, data, CONFIG);\n });\n };\n\n /**\n * _sanitizeElements\n *\n * @protect nodeName\n * @protect textContent\n * @protect removeChild\n *\n * @param {Node} currentNode to check for permission to exist\n * @return {Boolean} true if node was killed, false if left alive\n */\n const _sanitizeElements = function (currentNode) {\n let content = null;\n\n /* Execute a hook if present */\n _executeHook('beforeSanitizeElements', currentNode, null);\n\n /* Check if element is clobbered or can clobber */\n if (_isClobbered(currentNode)) {\n _forceRemove(currentNode);\n return true;\n }\n\n /* Now let's check the element's type and name */\n const tagName = transformCaseFunc(currentNode.nodeName);\n\n /* Execute a hook if present */\n _executeHook('uponSanitizeElement', currentNode, {\n tagName,\n allowedTags: ALLOWED_TAGS,\n });\n\n /* Detect mXSS attempts abusing namespace confusion */\n if (\n currentNode.hasChildNodes() &&\n !_isNode(currentNode.firstElementChild) &&\n regExpTest(/<[/\\w]/g, currentNode.innerHTML) &&\n regExpTest(/<[/\\w]/g, currentNode.textContent)\n ) {\n _forceRemove(currentNode);\n return true;\n }\n\n /* Remove element if anything forbids its presence */\n if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {\n /* Check if we have a custom element to handle */\n if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {\n if (\n CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp &&\n regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)\n ) {\n return false;\n }\n\n if (\n CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function &&\n CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)\n ) {\n return false;\n }\n }\n\n /* Keep content except for bad-listed elements */\n if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {\n const parentNode = getParentNode(currentNode) || currentNode.parentNode;\n const childNodes = getChildNodes(currentNode) || currentNode.childNodes;\n\n if (childNodes && parentNode) {\n const childCount = childNodes.length;\n\n for (let i = childCount - 1; i >= 0; --i) {\n parentNode.insertBefore(\n cloneNode(childNodes[i], true),\n getNextSibling(currentNode)\n );\n }\n }\n }\n\n _forceRemove(currentNode);\n return true;\n }\n\n /* Check whether element has a valid namespace */\n if (currentNode instanceof Element && !_checkValidNamespace(currentNode)) {\n _forceRemove(currentNode);\n return true;\n }\n\n /* Make sure that older browsers don't get fallback-tag mXSS */\n if (\n (tagName === 'noscript' ||\n tagName === 'noembed' ||\n tagName === 'noframes') &&\n regExpTest(/<\\/no(script|embed|frames)/i, currentNode.innerHTML)\n ) {\n _forceRemove(currentNode);\n return true;\n }\n\n /* Sanitize element content to be template-safe */\n if (SAFE_FOR_TEMPLATES && currentNode.nodeType === 3) {\n /* Get the element's text content */\n content = currentNode.textContent;\n\n arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], (expr) => {\n content = stringReplace(content, expr, ' ');\n });\n\n if (currentNode.textContent !== content) {\n arrayPush(DOMPurify.removed, { element: currentNode.cloneNode() });\n currentNode.textContent = content;\n }\n }\n\n /* Execute a hook if present */\n _executeHook('afterSanitizeElements', currentNode, null);\n\n return false;\n };\n\n /**\n * _isValidAttribute\n *\n * @param {string} lcTag Lowercase tag name of containing element.\n * @param {string} lcName Lowercase attribute name.\n * @param {string} value Attribute value.\n * @return {Boolean} Returns true if `value` is valid, otherwise false.\n */\n // eslint-disable-next-line complexity\n const _isValidAttribute = function (lcTag, lcName, value) {\n /* Make sure attribute cannot clobber */\n if (\n SANITIZE_DOM &&\n (lcName === 'id' || lcName === 'name') &&\n (value in document || value in formElement)\n ) {\n return false;\n }\n\n /* Allow valid data-* attributes: At least one character after \"-\"\n (https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes)\n XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804)\n We don't need to check the value; it's always URI safe. */\n if (\n ALLOW_DATA_ATTR &&\n !FORBID_ATTR[lcName] &&\n regExpTest(DATA_ATTR, lcName)\n ) {\n // This attribute is safe\n } else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR, lcName)) {\n // This attribute is safe\n /* Otherwise, check the name is permitted */\n } else if (!ALLOWED_ATTR[lcName] || FORBID_ATTR[lcName]) {\n if (\n // First condition does a very basic check if a) it's basically a valid custom element tagname AND\n // b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck\n // and c) if the attribute name passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.attributeNameCheck\n (_isBasicCustomElement(lcTag) &&\n ((CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp &&\n regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag)) ||\n (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function &&\n CUSTOM_ELEMENT_HANDLING.tagNameCheck(lcTag))) &&\n ((CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof RegExp &&\n regExpTest(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName)) ||\n (CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof Function &&\n CUSTOM_ELEMENT_HANDLING.attributeNameCheck(lcName)))) ||\n // Alternative, second condition checks if it's an `is`-attribute, AND\n // the value passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck\n (lcName === 'is' &&\n CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements &&\n ((CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp &&\n regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, value)) ||\n (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function &&\n CUSTOM_ELEMENT_HANDLING.tagNameCheck(value))))\n ) {\n // If user has supplied a regexp or function in CUSTOM_ELEMENT_HANDLING.tagNameCheck, we need to also allow derived custom elements using the same tagName test.\n // Additionally, we need to allow attributes passing the CUSTOM_ELEMENT_HANDLING.attributeNameCheck user has configured, as custom elements can define these at their own discretion.\n } else {\n return false;\n }\n /* Check value is safe. First, is attr inert? If so, is safe */\n } else if (URI_SAFE_ATTRIBUTES[lcName]) {\n // This attribute is safe\n /* Check no script, data or unknown possibly unsafe URI\n unless we know URI values are safe for that attribute */\n } else if (\n regExpTest(IS_ALLOWED_URI, stringReplace(value, ATTR_WHITESPACE, ''))\n ) {\n // This attribute is safe\n /* Keep image data URIs alive if src/xlink:href is allowed */\n /* Further prevent gadget XSS for dynamically built script tags */\n } else if (\n (lcName === 'src' || lcName === 'xlink:href' || lcName === 'href') &&\n lcTag !== 'script' &&\n stringIndexOf(value, 'data:') === 0 &&\n DATA_URI_TAGS[lcTag]\n ) {\n // This attribute is safe\n /* Allow unknown protocols: This provides support for links that\n are handled by protocol handlers which may be unknown ahead of\n time, e.g. fb:, spotify: */\n } else if (\n ALLOW_UNKNOWN_PROTOCOLS &&\n !regExpTest(IS_SCRIPT_OR_DATA, stringReplace(value, ATTR_WHITESPACE, ''))\n ) {\n // This attribute is safe\n /* Check for binary attributes */\n } else if (value) {\n return false;\n } else {\n // Binary attributes are safe at this point\n /* Anything else, presume unsafe, do not add it back */\n }\n\n return true;\n };\n\n /**\n * _isBasicCustomElement\n * checks if at least one dash is included in tagName, and it's not the first char\n * for more sophisticated checking see https://github.com/sindresorhus/validate-element-name\n *\n * @param {string} tagName name of the tag of the node to sanitize\n * @returns {boolean} Returns true if the tag name meets the basic criteria for a custom element, otherwise false.\n */\n const _isBasicCustomElement = function (tagName) {\n return tagName.indexOf('-') > 0;\n };\n\n /**\n * _sanitizeAttributes\n *\n * @protect attributes\n * @protect nodeName\n * @protect removeAttribute\n * @protect setAttribute\n *\n * @param {Node} currentNode to sanitize\n */\n const _sanitizeAttributes = function (currentNode) {\n /* Execute a hook if present */\n _executeHook('beforeSanitizeAttributes', currentNode, null);\n\n const { attributes } = currentNode;\n\n /* Check if we have attributes; if not we might have a text node */\n if (!attributes) {\n return;\n }\n\n const hookEvent = {\n attrName: '',\n attrValue: '',\n keepAttr: true,\n allowedAttributes: ALLOWED_ATTR,\n };\n let l = attributes.length;\n\n /* Go backwards over all attributes; safely remove bad ones */\n while (l--) {\n const attr = attributes[l];\n const { name, namespaceURI, value: attrValue } = attr;\n const lcName = transformCaseFunc(name);\n\n let value = name === 'value' ? attrValue : stringTrim(attrValue);\n\n /* Execute a hook if present */\n hookEvent.attrName = lcName;\n hookEvent.attrValue = value;\n hookEvent.keepAttr = true;\n hookEvent.forceKeepAttr = undefined; // Allows developers to see this is a property they can set\n _executeHook('uponSanitizeAttribute', currentNode, hookEvent);\n value = hookEvent.attrValue;\n /* Did the hooks approve of the attribute? */\n if (hookEvent.forceKeepAttr) {\n continue;\n }\n\n /* Remove attribute */\n _removeAttribute(name, currentNode);\n\n /* Did the hooks approve of the attribute? */\n if (!hookEvent.keepAttr) {\n continue;\n }\n\n /* Work around a security issue in jQuery 3.0 */\n if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(/\\/>/i, value)) {\n _removeAttribute(name, currentNode);\n continue;\n }\n\n /* Sanitize attribute content to be template-safe */\n if (SAFE_FOR_TEMPLATES) {\n arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], (expr) => {\n value = stringReplace(value, expr, ' ');\n });\n }\n\n /* Is `value` valid for this attribute? */\n const lcTag = transformCaseFunc(currentNode.nodeName);\n if (!_isValidAttribute(lcTag, lcName, value)) {\n continue;\n }\n\n /* Full DOM Clobbering protection via namespace isolation,\n * Prefix id and name attributes with `user-content-`\n */\n if (SANITIZE_NAMED_PROPS && (lcName === 'id' || lcName === 'name')) {\n // Remove the attribute with this value\n _removeAttribute(name, currentNode);\n\n // Prefix the value and later re-create the attribute with the sanitized value\n value = SANITIZE_NAMED_PROPS_PREFIX + value;\n }\n\n /* Handle attributes that require Trusted Types */\n if (\n trustedTypesPolicy &&\n typeof trustedTypes === 'object' &&\n typeof trustedTypes.getAttributeType === 'function'\n ) {\n if (namespaceURI) {\n /* Namespaces are not yet supported, see https://bugs.chromium.org/p/chromium/issues/detail?id=1305293 */\n } else {\n switch (trustedTypes.getAttributeType(lcTag, lcName)) {\n case 'TrustedHTML': {\n value = trustedTypesPolicy.createHTML(value);\n break;\n }\n\n case 'TrustedScriptURL': {\n value = trustedTypesPolicy.createScriptURL(value);\n break;\n }\n\n default: {\n break;\n }\n }\n }\n }\n\n /* Handle invalid data-* attribute set by try-catching it */\n try {\n if (namespaceURI) {\n currentNode.setAttributeNS(namespaceURI, name, value);\n } else {\n /* Fallback to setAttribute() for browser-unrecognized namespaces e.g. \"x-schema\". */\n currentNode.setAttribute(name, value);\n }\n\n arrayPop(DOMPurify.removed);\n } catch (_) {}\n }\n\n /* Execute a hook if present */\n _executeHook('afterSanitizeAttributes', currentNode, null);\n };\n\n /**\n * _sanitizeShadowDOM\n *\n * @param {DocumentFragment} fragment to iterate over recursively\n */\n const _sanitizeShadowDOM = function (fragment) {\n let shadowNode = null;\n const shadowIterator = _createNodeIterator(fragment);\n\n /* Execute a hook if present */\n _executeHook('beforeSanitizeShadowDOM', fragment, null);\n\n while ((shadowNode = shadowIterator.nextNode())) {\n /* Execute a hook if present */\n _executeHook('uponSanitizeShadowNode', shadowNode, null);\n\n /* Sanitize tags and elements */\n if (_sanitizeElements(shadowNode)) {\n continue;\n }\n\n /* Deep shadow DOM detected */\n if (shadowNode.content instanceof DocumentFragment) {\n _sanitizeShadowDOM(shadowNode.content);\n }\n\n /* Check attributes, sanitize if necessary */\n _sanitizeAttributes(shadowNode);\n }\n\n /* Execute a hook if present */\n _executeHook('afterSanitizeShadowDOM', fragment, null);\n };\n\n /**\n * Sanitize\n * Public method providing core sanitation functionality\n *\n * @param {String|Node} dirty string or DOM node\n * @param {Object} cfg object\n */\n // eslint-disable-next-line complexity\n DOMPurify.sanitize = function (dirty, cfg = {}) {\n let body = null;\n let importedNode = null;\n let currentNode = null;\n let returnNode = null;\n /* Make sure we have a string to sanitize.\n DO NOT return early, as this will return the wrong type if\n the user has requested a DOM object rather than a string */\n IS_EMPTY_INPUT = !dirty;\n if (IS_EMPTY_INPUT) {\n dirty = '';\n }\n\n /* Stringify, in case dirty is an object */\n if (typeof dirty !== 'string' && !_isNode(dirty)) {\n if (typeof dirty.toString === 'function') {\n dirty = dirty.toString();\n if (typeof dirty !== 'string') {\n throw typeErrorCreate('dirty is not a string, aborting');\n }\n } else {\n throw typeErrorCreate('toString is not a function');\n }\n }\n\n /* Return dirty HTML if DOMPurify cannot run */\n if (!DOMPurify.isSupported) {\n return dirty;\n }\n\n /* Assign config vars */\n if (!SET_CONFIG) {\n _parseConfig(cfg);\n }\n\n /* Clean up removed elements */\n DOMPurify.removed = [];\n\n /* Check if dirty is correctly typed for IN_PLACE */\n if (typeof dirty === 'string') {\n IN_PLACE = false;\n }\n\n if (IN_PLACE) {\n /* Do some early pre-sanitization to avoid unsafe root nodes */\n if (dirty.nodeName) {\n const tagName = transformCaseFunc(dirty.nodeName);\n if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {\n throw typeErrorCreate(\n 'root node is forbidden and cannot be sanitized in-place'\n );\n }\n }\n } else if (dirty instanceof Node) {\n /* If dirty is a DOM element, append to an empty document to avoid\n elements being stripped by the parser */\n body = _initDocument('');\n importedNode = body.ownerDocument.importNode(dirty, true);\n if (importedNode.nodeType === 1 && importedNode.nodeName === 'BODY') {\n /* Node is already a body, use as is */\n body = importedNode;\n } else if (importedNode.nodeName === 'HTML') {\n body = importedNode;\n } else {\n // eslint-disable-next-line unicorn/prefer-dom-node-append\n body.appendChild(importedNode);\n }\n } else {\n /* Exit directly if we have nothing to do */\n if (\n !RETURN_DOM &&\n !SAFE_FOR_TEMPLATES &&\n !WHOLE_DOCUMENT &&\n // eslint-disable-next-line unicorn/prefer-includes\n dirty.indexOf('<') === -1\n ) {\n return trustedTypesPolicy && RETURN_TRUSTED_TYPE\n ? trustedTypesPolicy.createHTML(dirty)\n : dirty;\n }\n\n /* Initialize the document to work on */\n body = _initDocument(dirty);\n\n /* Check we have a DOM node from the data */\n if (!body) {\n return RETURN_DOM ? null : RETURN_TRUSTED_TYPE ? emptyHTML : '';\n }\n }\n\n /* Remove first element node (ours) if FORCE_BODY is set */\n if (body && FORCE_BODY) {\n _forceRemove(body.firstChild);\n }\n\n /* Get node iterator */\n const nodeIterator = _createNodeIterator(IN_PLACE ? dirty : body);\n\n /* Now start iterating over the created document */\n while ((currentNode = nodeIterator.nextNode())) {\n /* Sanitize tags and elements */\n if (_sanitizeElements(currentNode)) {\n continue;\n }\n\n /* Shadow DOM detected, sanitize it */\n if (currentNode.content instanceof DocumentFragment) {\n _sanitizeShadowDOM(currentNode.content);\n }\n\n /* Check attributes, sanitize if necessary */\n _sanitizeAttributes(currentNode);\n }\n\n /* If we sanitized `dirty` in-place, return it. */\n if (IN_PLACE) {\n return dirty;\n }\n\n /* Return sanitized string or DOM */\n if (RETURN_DOM) {\n if (RETURN_DOM_FRAGMENT) {\n returnNode = createDocumentFragment.call(body.ownerDocument);\n\n while (body.firstChild) {\n // eslint-disable-next-line unicorn/prefer-dom-node-append\n returnNode.appendChild(body.firstChild);\n }\n } else {\n returnNode = body;\n }\n\n if (ALLOWED_ATTR.shadowroot || ALLOWED_ATTR.shadowrootmode) {\n /*\n AdoptNode() is not used because internal state is not reset\n (e.g. the past names map of a HTMLFormElement), this is safe\n in theory but we would rather not risk another attack vector.\n The state that is cloned by importNode() is explicitly defined\n by the specs.\n */\n returnNode = importNode.call(originalDocument, returnNode, true);\n }\n\n return returnNode;\n }\n\n let serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML;\n\n /* Serialize doctype if allowed */\n if (\n WHOLE_DOCUMENT &&\n ALLOWED_TAGS['!doctype'] &&\n body.ownerDocument &&\n body.ownerDocument.doctype &&\n body.ownerDocument.doctype.name &&\n regExpTest(EXPRESSIONS.DOCTYPE_NAME, body.ownerDocument.doctype.name)\n ) {\n serializedHTML =\n '\\n' + serializedHTML;\n }\n\n /* Sanitize final string template-safe */\n if (SAFE_FOR_TEMPLATES) {\n arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], (expr) => {\n serializedHTML = stringReplace(serializedHTML, expr, ' ');\n });\n }\n\n return trustedTypesPolicy && RETURN_TRUSTED_TYPE\n ? trustedTypesPolicy.createHTML(serializedHTML)\n : serializedHTML;\n };\n\n /**\n * Public method to set the configuration once\n * setConfig\n *\n * @param {Object} cfg configuration object\n */\n DOMPurify.setConfig = function (cfg = {}) {\n _parseConfig(cfg);\n SET_CONFIG = true;\n };\n\n /**\n * Public method to remove the configuration\n * clearConfig\n *\n */\n DOMPurify.clearConfig = function () {\n CONFIG = null;\n SET_CONFIG = false;\n };\n\n /**\n * Public method to check if an attribute value is valid.\n * Uses last set config, if any. Otherwise, uses config defaults.\n * isValidAttribute\n *\n * @param {String} tag Tag name of containing element.\n * @param {String} attr Attribute name.\n * @param {String} value Attribute value.\n * @return {Boolean} Returns true if `value` is valid. Otherwise, returns false.\n */\n DOMPurify.isValidAttribute = function (tag, attr, value) {\n /* Initialize shared config vars if necessary. */\n if (!CONFIG) {\n _parseConfig({});\n }\n\n const lcTag = transformCaseFunc(tag);\n const lcName = transformCaseFunc(attr);\n return _isValidAttribute(lcTag, lcName, value);\n };\n\n /**\n * AddHook\n * Public method to add DOMPurify hooks\n *\n * @param {String} entryPoint entry point for the hook to add\n * @param {Function} hookFunction function to execute\n */\n DOMPurify.addHook = function (entryPoint, hookFunction) {\n if (typeof hookFunction !== 'function') {\n return;\n }\n\n hooks[entryPoint] = hooks[entryPoint] || [];\n arrayPush(hooks[entryPoint], hookFunction);\n };\n\n /**\n * RemoveHook\n * Public method to remove a DOMPurify hook at a given entryPoint\n * (pops it from the stack of hooks if more are present)\n *\n * @param {String} entryPoint entry point for the hook to remove\n * @return {Function} removed(popped) hook\n */\n DOMPurify.removeHook = function (entryPoint) {\n if (hooks[entryPoint]) {\n return arrayPop(hooks[entryPoint]);\n }\n };\n\n /**\n * RemoveHooks\n * Public method to remove all DOMPurify hooks at a given entryPoint\n *\n * @param {String} entryPoint entry point for the hooks to remove\n */\n DOMPurify.removeHooks = function (entryPoint) {\n if (hooks[entryPoint]) {\n hooks[entryPoint] = [];\n }\n };\n\n /**\n * RemoveAllHooks\n * Public method to remove all DOMPurify hooks\n */\n DOMPurify.removeAllHooks = function () {\n hooks = {};\n };\n\n return DOMPurify;\n}\n\nexport default createDOMPurify();\n"],"names":["entries","setPrototypeOf","isFrozen","getPrototypeOf","getOwnPropertyDescriptor","Object","freeze","seal","create","apply","construct","Reflect","x","fun","thisValue","args","Func","arrayForEach","unapply","Array","prototype","forEach","arrayPop","pop","arrayPush","push","stringToLowerCase","String","toLowerCase","stringToString","toString","stringMatch","match","stringReplace","replace","stringIndexOf","indexOf","stringTrim","trim","regExpTest","RegExp","test","typeErrorCreate","func","TypeError","_len2","arguments","length","_key2","thisArg","_len","_key","addToSet","set","array","transformCaseFunc","l","element","lcElement","clone","object","newObject","property","value","undefined","lookupGetter","prop","desc","get","fallbackValue","console","warn","html","svg","svgFilters","svgDisallowed","mathMl","mathMlDisallowed","text","xml","MUSTACHE_EXPR","ERB_EXPR","TMPLIT_EXPR","DATA_ATTR","ARIA_ATTR","IS_ALLOWED_URI","IS_SCRIPT_OR_DATA","ATTR_WHITESPACE","DOCTYPE_NAME","getGlobal","window","_createTrustedTypesPolicy","trustedTypes","purifyHostElement","createPolicy","suffix","ATTR_NAME","hasAttribute","getAttribute","policyName","createHTML","createScriptURL","scriptUrl","_","purify","createDOMPurify","DOMPurify","root","version","VERSION","removed","document","nodeType","isSupported","originalDocument","currentScript","DocumentFragment","HTMLTemplateElement","Node","Element","NodeFilter","NamedNodeMap","MozNamedAttrMap","HTMLFormElement","DOMParser","ElementPrototype","cloneNode","getNextSibling","getChildNodes","getParentNode","template","createElement","content","ownerDocument","trustedTypesPolicy","emptyHTML","implementation","createNodeIterator","createDocumentFragment","getElementsByTagName","importNode","hooks","createHTMLDocument","EXPRESSIONS","ALLOWED_TAGS","DEFAULT_ALLOWED_TAGS","TAGS","ALLOWED_ATTR","DEFAULT_ALLOWED_ATTR","ATTRS","CUSTOM_ELEMENT_HANDLING","tagNameCheck","writable","configurable","enumerable","attributeNameCheck","allowCustomizedBuiltInElements","FORBID_TAGS","FORBID_ATTR","ALLOW_ARIA_ATTR","ALLOW_DATA_ATTR","ALLOW_UNKNOWN_PROTOCOLS","ALLOW_SELF_CLOSE_IN_ATTR","SAFE_FOR_TEMPLATES","WHOLE_DOCUMENT","SET_CONFIG","FORCE_BODY","RETURN_DOM","RETURN_DOM_FRAGMENT","RETURN_TRUSTED_TYPE","SANITIZE_DOM","SANITIZE_NAMED_PROPS","SANITIZE_NAMED_PROPS_PREFIX","KEEP_CONTENT","IN_PLACE","USE_PROFILES","FORBID_CONTENTS","DEFAULT_FORBID_CONTENTS","DATA_URI_TAGS","DEFAULT_DATA_URI_TAGS","URI_SAFE_ATTRIBUTES","DEFAULT_URI_SAFE_ATTRIBUTES","MATHML_NAMESPACE","SVG_NAMESPACE","HTML_NAMESPACE","NAMESPACE","IS_EMPTY_INPUT","ALLOWED_NAMESPACES","DEFAULT_ALLOWED_NAMESPACES","PARSER_MEDIA_TYPE","SUPPORTED_PARSER_MEDIA_TYPES","DEFAULT_PARSER_MEDIA_TYPE","CONFIG","formElement","isRegexOrFunction","testValue","Function","_parseConfig","cfg","ADD_URI_SAFE_ATTR","ADD_DATA_URI_TAGS","ALLOWED_URI_REGEXP","ADD_TAGS","ADD_ATTR","table","tbody","TRUSTED_TYPES_POLICY","MATHML_TEXT_INTEGRATION_POINTS","HTML_INTEGRATION_POINTS","COMMON_SVG_AND_HTML_ELEMENTS","ALL_SVG_TAGS","ALL_MATHML_TAGS","_checkValidNamespace","parent","tagName","namespaceURI","parentTagName","Boolean","_forceRemove","node","parentNode","removeChild","remove","_removeAttribute","name","attribute","getAttributeNode","from","removeAttribute","setAttribute","_initDocument","dirty","doc","leadingWhitespace","matches","dirtyPayload","parseFromString","documentElement","createDocument","innerHTML","body","insertBefore","createTextNode","childNodes","call","_createNodeIterator","SHOW_ELEMENT","SHOW_COMMENT","SHOW_TEXT","_isClobbered","elm","nodeName","textContent","attributes","hasChildNodes","_isNode","_executeHook","entryPoint","currentNode","data","hook","_sanitizeElements","allowedTags","firstElementChild","_isBasicCustomElement","i","expr","_isValidAttribute","lcTag","lcName","_sanitizeAttributes","hookEvent","attrName","attrValue","keepAttr","allowedAttributes","attr","forceKeepAttr","getAttributeType","setAttributeNS","_sanitizeShadowDOM","fragment","shadowNode","shadowIterator","nextNode","sanitize","importedNode","returnNode","appendChild","firstChild","nodeIterator","shadowroot","shadowrootmode","serializedHTML","outerHTML","doctype","setConfig","clearConfig","isValidAttribute","tag","addHook","hookFunction","removeHook","removeHooks","removeAllHooks"],"mappings":";0OAAA,MAAMA,QACJA,EADIC,eAEJA,EAFIC,SAGJA,EAHIC,eAIJA,EAJIC,yBAKJA,GACEC,OAEJ,IAAIC,OAAEA,EAAFC,KAAUA,EAAVC,OAAgBA,GAAWH,QAC3BI,MAAEA,EAAFC,UAASA,GAAiC,oBAAZC,SAA2BA,QAExDL,IACHA,EAAS,SAAUM,GACjB,OAAOA,CACR,GAGEL,IACHA,EAAO,SAAUK,GACf,OAAOA,CACR,GAGEH,IACHA,EAAQ,SAAUI,EAAKC,EAAWC,GAChC,OAAOF,EAAIJ,MAAMK,EAAWC,EAC7B,GAGEL,IACHA,EAAY,SAAUM,EAAMD,GAC1B,OAAO,IAAIC,KAAQD,EACpB,GAGH,MAAME,EAAeC,EAAQC,MAAMC,UAAUC,SAEvCC,EAAWJ,EAAQC,MAAMC,UAAUG,KACnCC,EAAYN,EAAQC,MAAMC,UAAUK,MAGpCC,EAAoBR,EAAQS,OAAOP,UAAUQ,aAC7CC,EAAiBX,EAAQS,OAAOP,UAAUU,UAC1CC,EAAcb,EAAQS,OAAOP,UAAUY,OACvCC,EAAgBf,EAAQS,OAAOP,UAAUc,SACzCC,EAAgBjB,EAAQS,OAAOP,UAAUgB,SACzCC,EAAanB,EAAQS,OAAOP,UAAUkB,MAEtCC,EAAarB,EAAQsB,OAAOpB,UAAUqB,MAEtCC,GAkBeC,EAlBeC,UAmB3B,WAAA,IAAA,IAAAC,EAAAC,UAAAC,OAAIhC,EAAJ,IAAAI,MAAA0B,GAAAG,EAAA,EAAAA,EAAAH,EAAAG,IAAIjC,EAAJiC,GAAAF,UAAAE,GAAA,OAAatC,EAAUiC,EAAM5B,EAA7B,GADT,IAAqB4B,EAVrB,SAASzB,EAAQyB,GACf,OAAO,SAACM,GAAD,IAAA,IAAAC,EAAAJ,UAAAC,OAAahC,EAAb,IAAAI,MAAA+B,EAAA,EAAAA,EAAA,EAAA,GAAAC,EAAA,EAAAA,EAAAD,EAAAC,IAAapC,EAAboC,EAAA,GAAAL,UAAAK,GAAA,OAAsB1C,EAAMkC,EAAMM,EAASlC,EAA3C,CACR,CAoBD,SAASqC,EAASC,EAAKC,GAAOC,IAAAA,yDAAoB7B,EAC5CzB,GAIFA,EAAeoD,EAAK,MAGtB,IAAIG,EAAIF,EAAMP,OACPS,KAAAA,KAAK,CACV,IAAIC,EAAUH,EAAME,GACpB,GAAuB,iBAAZC,EAAsB,CAC/B,MAAMC,EAAYH,EAAkBE,GAChCC,IAAcD,IAEXvD,EAASoD,KACZA,EAAME,GAAKE,GAGbD,EAAUC,EAEb,CAEDL,EAAII,IAAW,CAChB,CAED,OAAOJ,CACR,CAQM,SAASM,EAAMC,GACpB,MAAMC,EAAYrD,EAAO,MAEpB,IAAA,MAAOsD,EAAUC,KAAU/D,EAAQ4D,QACaI,IAA/C5D,EAAyBwD,EAAQE,KACnCD,EAAUC,GAAYC,GAI1B,OAAOF,CACR,CASD,SAASI,EAAaL,EAAQM,GACrBN,KAAW,OAAXA,GAAiB,CACtB,MAAMO,EAAO/D,EAAyBwD,EAAQM,GAE9C,GAAIC,EAAM,CACJA,GAAAA,EAAKC,IACP,OAAOlD,EAAQiD,EAAKC,KAGtB,GAA0B,mBAAfD,EAAKJ,MACd,OAAO7C,EAAQiD,EAAKJ,MAEvB,CAEDH,EAASzD,EAAeyD,EACzB,CAOD,OALSS,SAAcZ,GAErB,OADAa,QAAQC,KAAK,qBAAsBd,GAC5B,IACR,CAGF,CC3JM,MAAMe,EAAOlE,EAAO,CACzB,IACA,OACA,UACA,UACA,OACA,UACA,QACA,QACA,IACA,MACA,MACA,MACA,QACA,aACA,OACA,KACA,SACA,SACA,UACA,SACA,OACA,OACA,MACA,WACA,UACA,OACA,WACA,KACA,YACA,MACA,UACA,MACA,SACA,MACA,MACA,KACA,KACA,UACA,KACA,WACA,aACA,SACA,OACA,SACA,OACA,KACA,KACA,KACA,KACA,KACA,KACA,OACA,SACA,SACA,KACA,OACA,IACA,MACA,QACA,MACA,MACA,QACA,SACA,KACA,OACA,MACA,OACA,UACA,OACA,WACA,QACA,MACA,OACA,KACA,WACA,SACA,SACA,IACA,UACA,MACA,WACA,IACA,KACA,KACA,OACA,IACA,OACA,UACA,SACA,SACA,QACA,SACA,SACA,OACA,SACA,SACA,QACA,MACA,UACA,MACA,QACA,QACA,KACA,WACA,WACA,QACA,KACA,QACA,OACA,KACA,QACA,KACA,IACA,KACA,MACA,QACA,QAIWmE,EAAMnE,EAAO,CACxB,MACA,IACA,WACA,cACA,eACA,eACA,gBACA,mBACA,SACA,WACA,OACA,OACA,UACA,SACA,OACA,IACA,QACA,WACA,QACA,QACA,OACA,iBACA,SACA,OACA,WACA,QACA,OACA,UACA,UACA,WACA,iBACA,OACA,OACA,QACA,SACA,SACA,OACA,WACA,QACA,OACA,QACA,OACA,UAGWoE,EAAapE,EAAO,CAC/B,UACA,gBACA,sBACA,cACA,mBACA,oBACA,oBACA,iBACA,eACA,UACA,UACA,UACA,UACA,UACA,iBACA,UACA,UACA,cACA,eACA,WACA,eACA,qBACA,cACA,SACA,iBAOWqE,EAAgBrE,EAAO,CAClC,UACA,gBACA,SACA,UACA,YACA,mBACA,iBACA,gBACA,gBACA,gBACA,QACA,YACA,OACA,eACA,YACA,UACA,gBACA,SACA,MACA,aACA,UACA,QAGWsE,EAAStE,EAAO,CAC3B,OACA,WACA,SACA,UACA,QACA,SACA,KACA,aACA,gBACA,KACA,KACA,QACA,UACA,WACA,QACA,OACA,KACA,SACA,QACA,SACA,OACA,OACA,UACA,SACA,MACA,QACA,MACA,SACA,aACA,gBAKWuE,EAAmBvE,EAAO,CACrC,UACA,cACA,aACA,WACA,YACA,UACA,UACA,SACA,SACA,QACA,YACA,aACA,iBACA,cACA,SAGWwE,EAAOxE,EAAO,CAAC,UCrRfkE,EAAOlE,EAAO,CACzB,SACA,SACA,QACA,MACA,iBACA,eACA,uBACA,WACA,aACA,UACA,SACA,UACA,cACA,cACA,UACA,OACA,QACA,QACA,QACA,OACA,UACA,WACA,eACA,SACA,cACA,WACA,WACA,UACA,MACA,WACA,0BACA,wBACA,WACA,YACA,UACA,eACA,OACA,MACA,UACA,SACA,SACA,OACA,OACA,WACA,KACA,YACA,YACA,QACA,OACA,QACA,OACA,OACA,UACA,OACA,MACA,MACA,YACA,QACA,SACA,MACA,YACA,WACA,QACA,OACA,QACA,UACA,aACA,SACA,OACA,UACA,UACA,cACA,cACA,SACA,UACA,UACA,aACA,WACA,MACA,WACA,MACA,WACA,OACA,OACA,UACA,aACA,QACA,WACA,QACA,OACA,QACA,OACA,UACA,QACA,MACA,SACA,OACA,QACA,UACA,WACA,QACA,YACA,OACA,SACA,SACA,QACA,QACA,QACA,SAGWmE,EAAMnE,EAAO,CACxB,gBACA,aACA,WACA,qBACA,SACA,gBACA,gBACA,UACA,gBACA,iBACA,QACA,OACA,KACA,QACA,OACA,gBACA,YACA,YACA,QACA,sBACA,8BACA,gBACA,kBACA,KACA,KACA,IACA,KACA,KACA,kBACA,YACA,UACA,UACA,MACA,WACA,YACA,MACA,OACA,eACA,YACA,SACA,cACA,cACA,gBACA,cACA,YACA,mBACA,eACA,aACA,eACA,cACA,KACA,KACA,KACA,KACA,aACA,WACA,gBACA,oBACA,SACA,OACA,KACA,kBACA,KACA,MACA,IACA,KACA,KACA,KACA,KACA,UACA,YACA,aACA,WACA,OACA,eACA,iBACA,eACA,mBACA,iBACA,QACA,aACA,aACA,eACA,eACA,cACA,cACA,mBACA,YACA,MACA,OACA,QACA,SACA,OACA,MACA,OACA,aACA,SACA,WACA,UACA,QACA,SACA,cACA,SACA,WACA,cACA,OACA,aACA,sBACA,mBACA,eACA,SACA,gBACA,sBACA,iBACA,IACA,KACA,KACA,SACA,OACA,OACA,cACA,YACA,UACA,SACA,SACA,QACA,OACA,kBACA,mBACA,mBACA,eACA,cACA,eACA,cACA,aACA,eACA,mBACA,oBACA,iBACA,kBACA,oBACA,iBACA,SACA,eACA,QACA,eACA,iBACA,WACA,UACA,UACA,YACA,mBACA,cACA,kBACA,iBACA,aACA,OACA,KACA,KACA,UACA,SACA,UACA,aACA,UACA,aACA,gBACA,gBACA,QACA,eACA,OACA,eACA,mBACA,mBACA,IACA,KACA,KACA,QACA,IACA,KACA,KACA,IACA,eAGWsE,EAAStE,EAAO,CAC3B,SACA,cACA,QACA,WACA,QACA,eACA,cACA,aACA,aACA,QACA,MACA,UACA,eACA,WACA,QACA,QACA,SACA,OACA,KACA,UACA,SACA,gBACA,SACA,SACA,iBACA,YACA,WACA,cACA,UACA,UACA,gBACA,WACA,WACA,OACA,WACA,WACA,aACA,UACA,SACA,SACA,cACA,gBACA,uBACA,YACA,YACA,aACA,WACA,iBACA,iBACA,YACA,UACA,QACA,UAGWyE,EAAMzE,EAAO,CACxB,aACA,SACA,cACA,YACA,gBCrWW0E,EAAgBzE,EAAK,6BACrB0E,EAAW1E,EAAK,yBAChB2E,EAAc3E,EAAK,iBACnB4E,EAAY5E,EAAK,8BACjB6E,EAAY7E,EAAK,kBACjB8E,EAAiB9E,EAC5B,6FAEW+E,EAAoB/E,EAAK,yBACzBgF,EAAkBhF,EAC7B,+DAEWiF,EAAejF,EAAK,wLCQjC,MAAMkF,EAAY,WAChB,MAAyB,oBAAXC,OAAyB,KAAOA,MAC/C,EAUKC,EAA4B,SAAUC,EAAcC,GAEtD,GAAwB,iBAAjBD,GAC8B,mBAA9BA,EAAaE,aAEpB,OAAO,KAMLC,IAAAA,EAAS,KACPC,MAAAA,EAAY,wBACdH,GAAqBA,EAAkBI,aAAaD,KACtDD,EAASF,EAAkBK,aAAaF,IAGpCG,MAAAA,EAAa,aAAeJ,EAAS,IAAMA,EAAS,IAEtD,IACF,OAAOH,EAAaE,aAAaK,EAAY,CAC3CC,WAAW5B,GACFA,EAET6B,gBAAgBC,GACPA,GAWZ,CARC,MAAOC,GAOP,OAHAjC,QAAQC,KACN,uBAAyB4B,EAAa,0BAEjC,IACR,CACF,EA4hDD,IAAAK,EA1hDA,SAASC,IAAgBf,IAAAA,EAASD,UAAAA,OAAAA,QAAAA,IAAAA,UAAAA,GAAAA,UAAAA,GAAAA,IAChC,MAAMiB,EAAaC,GAASF,EAAgBE,GAc5C,GARAD,EAAUE,QAAUC,QAMpBH,EAAUI,QAAU,IAEfpB,IAAWA,EAAOqB,UAAyC,IAA7BrB,EAAOqB,SAASC,SAKjD,OAFAN,EAAUO,aAAc,EAEjBP,EAGL,IAAAK,SAAEA,GAAarB,EAEbwB,MAAAA,EAAmBH,EACnBI,EAAgBD,EAAiBC,eACjCC,iBACJA,EADIC,oBAEJA,EAFIC,KAGJA,EAHIC,QAIJA,EAJIC,WAKJA,EALIC,aAMJA,EAAe/B,EAAO+B,cAAgB/B,EAAOgC,gBANzCC,gBAOJA,EAPIC,UAQJA,EARIhC,aASJA,GACEF,EAEEmC,EAAmBN,EAAQnG,UAE3B0G,EAAY7D,EAAa4D,EAAkB,aAC3CE,EAAiB9D,EAAa4D,EAAkB,eAChDG,EAAgB/D,EAAa4D,EAAkB,cAC/CI,EAAgBhE,EAAa4D,EAAkB,cAQrD,GAAmC,mBAAxBR,EAAoC,CAC7C,MAAMa,EAAWnB,EAASoB,cAAc,YACpCD,EAASE,SAAWF,EAASE,QAAQC,gBACvCtB,EAAWmB,EAASE,QAAQC,cAE/B,CAED,IAAIC,EACAC,GAAY,GAEV,MAAAC,eACJA,GADIC,mBAEJA,GAFIC,uBAGJA,GAHIC,qBAIJA,IACE5B,GACE6B,WAAEA,IAAe1B,EAEnB2B,IAAAA,GAAQ,CAAA,EAKZnC,EAAUO,YACW,mBAAZjH,GACkB,mBAAlBiI,GACPO,SACsCxE,IAAtCwE,GAAeM,mBAEX,MAAA9D,cACJA,GADIC,SAEJA,GAFIC,YAGJA,GAHIC,UAIJA,GAJIC,UAKJA,GALIE,kBAMJA,GANIC,gBAOJA,IACEwD,EAEA,IAAE1D,eAAAA,IAAmB0D,EAQrBC,GAAe,KACnB,MAAMC,GAAuB7F,EAAS,GAAI,IACrC8F,KACAA,KACAA,KACAA,KACAA,IAIDC,IAAAA,GAAe,KACbC,MAAAA,GAAuBhG,EAAS,CAAD,EAAK,IACrCiG,KACAA,KACAA,KACAA,IASDC,IAAAA,GAA0BjJ,OAAOE,KACnCC,EAAO,KAAM,CACX+I,aAAc,CACZC,UAAU,EACVC,cAAc,EACdC,YAAY,EACZ3F,MAAO,MAET4F,mBAAoB,CAClBH,UAAU,EACVC,cAAc,EACdC,YAAY,EACZ3F,MAAO,MAET6F,+BAAgC,CAC9BJ,UAAU,EACVC,cAAc,EACdC,YAAY,EACZ3F,OAAO,MAMT8F,GAAc,KAGdC,GAAc,KAGdC,IAAkB,EAGlBC,IAAkB,EAGlBC,IAA0B,EAI1BC,IAA2B,EAK3BC,IAAqB,EAGrBC,IAAiB,EAGjBC,IAAa,EAIbC,IAAa,EAMbC,IAAa,EAIbC,IAAsB,EAItBC,IAAsB,EAKtBC,IAAe,EAefC,IAAuB,EACrBC,MAAAA,GAA8B,gBAGhCC,IAAAA,IAAe,EAIfC,IAAW,EAGXC,GAAe,CAAA,EAGfC,GAAkB,KAChBC,MAAAA,GAA0B7H,EAAS,CAAD,EAAK,CAC3C,iBACA,QACA,WACA,OACA,gBACA,OACA,SACA,OACA,KACA,KACA,KACA,KACA,QACA,UACA,WACA,WACA,YACA,SACA,QACA,MACA,WACA,QACA,QACA,QACA,QAIE8H,IAAAA,GAAgB,KACpB,MAAMC,GAAwB/H,EAAS,CAAD,EAAK,CACzC,QACA,QACA,MACA,SACA,QACA,UAIEgI,IAAAA,GAAsB,KAC1B,MAAMC,GAA8BjI,EAAS,GAAI,CAC/C,MACA,QACA,MACA,KACA,QACA,OACA,UACA,cACA,OACA,UACA,QACA,QACA,QACA,UAGIkI,GAAmB,qCACnBC,GAAgB,6BAChBC,GAAiB,+BAEnBC,IAAAA,GAAYD,GACZE,IAAiB,EAGjBC,GAAqB,KACzB,MAAMC,GAA6BxI,EACjC,GACA,CAACkI,GAAkBC,GAAeC,IAClC3J,GAIEgK,IAAAA,GAAoB,KACxB,MAAMC,GAA+B,CAAC,wBAAyB,aACzDC,GAA4B,YAC9BxI,IAAAA,GAAoB,KAGpByI,GAAS,KAKb,MAAMC,GAAclF,EAASoB,cAAc,QAErC+D,GAAoB,SAAUC,GAClC,OAAOA,aAAqB3J,QAAU2J,aAAqBC,QAC5D,EAQKC,GAAe,WAAUC,IAAAA,yDAAM,CAAA,EACnC,IAAIN,IAAUA,KAAWM,EAAzB,CA6LIA,GAxLCA,GAAsB,iBAARA,IACjBA,EAAM,CAAA,GAIRA,EAAM3I,EAAM2I,GAEZT,GAGOA,IAD4D,IAAjEC,GAA6B1J,QAAQkK,EAAIT,mBAChBE,GACAO,EAAIT,kBAG/BtI,GACwB,0BAAtBsI,GACIhK,EACAH,EAGNsH,GACE,iBAAkBsD,EACdlJ,EAAS,CAAA,EAAIkJ,EAAItD,aAAczF,IAC/B0F,GACNE,GACE,iBAAkBmD,EACdlJ,EAAS,CAAA,EAAIkJ,EAAInD,aAAc5F,IAC/B6F,GACNuC,GACE,uBAAwBW,EACpBlJ,EAAS,CAAA,EAAIkJ,EAAIX,mBAAoB9J,GACrC+J,GACNR,GACE,sBAAuBkB,EACnBlJ,EACEO,EAAM0H,IACNiB,EAAIC,kBACJhJ,IAEF8H,GACNH,GACE,sBAAuBoB,EACnBlJ,EACEO,EAAMwH,IACNmB,EAAIE,kBACJjJ,IAEF4H,GACNH,GACE,oBAAqBsB,EACjBlJ,EAAS,CAAA,EAAIkJ,EAAItB,gBAAiBzH,IAClC0H,GACNpB,GACE,gBAAiByC,EACblJ,EAAS,CAAA,EAAIkJ,EAAIzC,YAAatG,IAC9B,GACNuG,GACE,gBAAiBwC,EACblJ,EAAS,CAAA,EAAIkJ,EAAIxC,YAAavG,IAC9B,GACNwH,GAAe,iBAAkBuB,GAAMA,EAAIvB,aAC3ChB,IAA0C,IAAxBuC,EAAIvC,gBACtBC,IAA0C,IAAxBsC,EAAItC,gBACtBC,GAA0BqC,EAAIrC,0BAA2B,EACzDC,IAA4D,IAAjCoC,EAAIpC,yBAC/BC,GAAqBmC,EAAInC,qBAAsB,EAC/CC,GAAiBkC,EAAIlC,iBAAkB,EACvCG,GAAa+B,EAAI/B,aAAc,EAC/BC,GAAsB8B,EAAI9B,sBAAuB,EACjDC,GAAsB6B,EAAI7B,sBAAuB,EACjDH,GAAagC,EAAIhC,aAAc,EAC/BI,IAAoC,IAArB4B,EAAI5B,aACnBC,GAAuB2B,EAAI3B,uBAAwB,EACnDE,IAAoC,IAArByB,EAAIzB,aACnBC,GAAWwB,EAAIxB,WAAY,EAC3BzF,GAAiBiH,EAAIG,oBAAsB1D,EAC3C0C,GAAYa,EAAIb,WAAaD,GAC7BlC,GAA0BgD,EAAIhD,yBAA2B,GAEvDgD,EAAIhD,yBACJ4C,GAAkBI,EAAIhD,wBAAwBC,gBAE9CD,GAAwBC,aACtB+C,EAAIhD,wBAAwBC,cAI9B+C,EAAIhD,yBACJ4C,GAAkBI,EAAIhD,wBAAwBK,sBAE9CL,GAAwBK,mBACtB2C,EAAIhD,wBAAwBK,oBAI9B2C,EAAIhD,yBAEF,kBADKgD,EAAIhD,wBAAwBM,iCAGnCN,GAAwBM,+BACtB0C,EAAIhD,wBAAwBM,gCAG5BO,KACFH,IAAkB,GAGhBQ,KACFD,IAAa,GAIXQ,KACF/B,GAAe5F,EAAS,CAAA,EAAI,IAAI8F,IAChCC,GAAe,IACW,IAAtB4B,GAAavG,OACfpB,EAAS4F,GAAcE,GACvB9F,EAAS+F,GAAcE,KAGA,IAArB0B,GAAatG,MACfrB,EAAS4F,GAAcE,GACvB9F,EAAS+F,GAAcE,GACvBjG,EAAS+F,GAAcE,KAGO,IAA5B0B,GAAarG,aACftB,EAAS4F,GAAcE,GACvB9F,EAAS+F,GAAcE,GACvBjG,EAAS+F,GAAcE,KAGG,IAAxB0B,GAAanG,SACfxB,EAAS4F,GAAcE,GACvB9F,EAAS+F,GAAcE,GACvBjG,EAAS+F,GAAcE,KAKvBiD,EAAII,WACF1D,KAAiBC,KACnBD,GAAerF,EAAMqF,KAGvB5F,EAAS4F,GAAcsD,EAAII,SAAUnJ,KAGnC+I,EAAIK,WACFxD,KAAiBC,KACnBD,GAAexF,EAAMwF,KAGvB/F,EAAS+F,GAAcmD,EAAIK,SAAUpJ,KAGnC+I,EAAIC,mBACNnJ,EAASgI,GAAqBkB,EAAIC,kBAAmBhJ,IAGnD+I,EAAItB,kBACFA,KAAoBC,KACtBD,GAAkBrH,EAAMqH,KAG1B5H,EAAS4H,GAAiBsB,EAAItB,gBAAiBzH,KAI7CsH,KACF7B,GAAa,UAAW,GAItBoB,IACFhH,EAAS4F,GAAc,CAAC,OAAQ,OAAQ,SAItCA,GAAa4D,QACfxJ,EAAS4F,GAAc,CAAC,iBACjBa,GAAYgD,OAGjBP,EAAIQ,qBAAsB,CACxB,GAA+C,mBAAxCR,EAAIQ,qBAAqB1G,WAC5B1D,MAAAA,EACJ,+EAIA,GAAoD,mBAA7C4J,EAAIQ,qBAAqBzG,gBAC5B3D,MAAAA,EACJ,oFAKJ4F,EAAqBgE,EAAIQ,qBAGzBvE,GAAYD,EAAmBlC,WAAW,GAC3C,WAE4BpC,IAAvBsE,IACFA,EAAqB3C,EACnBC,EACAuB,IAKuB,OAAvBmB,GAAoD,iBAAdC,KACxCA,GAAYD,EAAmBlC,WAAW,KAM1C9F,GACFA,EAAOgM,GAGTN,GAASM,CAlOR,CAmOF,EAEKS,GAAiC3J,EAAS,CAAA,EAAI,CAClD,KACA,KACA,KACA,KACA,UAGI4J,GAA0B5J,EAAS,GAAI,CAC3C,gBACA,OACA,QACA,mBAOI6J,GAA+B7J,EAAS,CAAA,EAAI,CAChD,QACA,QACA,OACA,IACA,WAMI8J,GAAe9J,EAAS,CAAD,EAAK8F,GAClC9F,EAAS8J,GAAchE,GACvB9F,EAAS8J,GAAchE,GAEjBiE,MAAAA,GAAkB/J,EAAS,CAAD,EAAK8F,GACrC9F,EAAS+J,GAAiBjE,GAQ1B,MAAMkE,GAAuB,SAAU3J,GACrC,IAAI4J,EAASpF,EAAcxE,GAItB4J,GAAWA,EAAOC,UACrBD,EAAS,CACPE,aAAc9B,GACd6B,QAAS,aAIb,MAAMA,EAAU5L,EAAkB+B,EAAQ6J,SACpCE,EAAgB9L,EAAkB2L,EAAOC,SAE/C,QAAK3B,GAAmBlI,EAAQ8J,gBAI5B9J,EAAQ8J,eAAiBhC,GAIvB8B,EAAOE,eAAiB/B,GACP,QAAZ8B,EAMLD,EAAOE,eAAiBjC,GAEZ,QAAZgC,IACmB,mBAAlBE,GACCT,GAA+BS,IAM9BC,QAAQP,GAAaI,IAG1B7J,EAAQ8J,eAAiBjC,GAIvB+B,EAAOE,eAAiB/B,GACP,SAAZ8B,EAKLD,EAAOE,eAAiBhC,GACP,SAAZ+B,GAAsBN,GAAwBQ,GAKhDC,QAAQN,GAAgBG,IAG7B7J,EAAQ8J,eAAiB/B,KAKzB6B,EAAOE,eAAiBhC,KACvByB,GAAwBQ,QAMzBH,EAAOE,eAAiBjC,KACvByB,GAA+BS,OAQ/BL,GAAgBG,KAChBL,GAA6BK,KAAaJ,GAAaI,QAMpC,0BAAtBzB,KACAF,GAAmBlI,EAAQ8J,eAU9B,EAOKG,GAAe,SAAUC,GAC7BnM,EAAUkF,EAAUI,QAAS,CAAErD,QAASkK,IACpC,IAEFA,EAAKC,WAAWC,YAAYF,EAG7B,CAFC,MAAOpH,GACPoH,EAAKG,QACN,CACF,EAQKC,GAAmB,SAAUC,EAAML,GACnC,IACFnM,EAAUkF,EAAUI,QAAS,CAC3BmH,UAAWN,EAAKO,iBAAiBF,GACjCG,KAAMR,GAOT,CALC,MAAOpH,GACP/E,EAAUkF,EAAUI,QAAS,CAC3BmH,UAAW,KACXE,KAAMR,GAET,CAKGK,GAHJL,EAAKS,gBAAgBJ,GAGR,OAATA,IAAkB7E,GAAa6E,GAC7BzD,GAAAA,IAAcC,GACZ,IACFkD,GAAaC,EACD,CAAZ,MAAOpH,GAAK,MAEV,IACFoH,EAAKU,aAAaL,EAAM,GACZ,CAAZ,MAAOzH,GAAK,CAGnB,EAQK+H,GAAgB,SAAUC,GAE1BC,IAAAA,EAAM,KACNC,EAAoB,KAExB,GAAInE,GACFiE,EAAQ,oBAAsBA,MACzB,CAEL,MAAMG,EAAU3M,EAAYwM,EAAO,eACnCE,EAAoBC,GAAWA,EAAQ,EACxC,CAGuB,0BAAtB7C,IACAJ,KAAcD,KAGd+C,EACE,iEACAA,EACA,kBAGEI,MAAAA,EAAerG,EACjBA,EAAmBlC,WAAWmI,GAC9BA,EAKA9C,GAAAA,KAAcD,GACZ,IACFgD,GAAM,IAAI5G,GAAYgH,gBAAgBD,EAAc9C,GACxC,CAAZ,MAAOtF,GAAK,CAIhB,IAAKiI,IAAQA,EAAIK,gBAAiB,CAChCL,EAAMhG,GAAesG,eAAerD,GAAW,WAAY,MACvD,IACF+C,EAAIK,gBAAgBE,UAAYrD,GAC5BnD,GACAoG,CAGL,CAFC,MAAOpI,GAER,CACF,CAEKyI,MAAAA,EAAOR,EAAIQ,MAAQR,EAAIK,gBAUzBpD,OARA8C,GAASE,GACXO,EAAKC,aACHlI,EAASmI,eAAeT,GACxBO,EAAKG,WAAW,IAAM,MAKtB1D,KAAcD,GACT7C,GAAqByG,KAC1BZ,EACApE,GAAiB,OAAS,QAC1B,GAGGA,GAAiBoE,EAAIK,gBAAkBG,CAC/C,EAQKK,GAAsB,SAAU1I,GAC7B8B,OAAAA,GAAmB2G,KACxBzI,EAAK0B,eAAiB1B,EACtBA,EAEAa,EAAW8H,aAAe9H,EAAW+H,aAAe/H,EAAWgI,UAC/D,KAEH,EAQKC,GAAe,SAAUC,GAC7B,OACEA,aAAe/H,IACU,iBAAjB+H,EAAIC,UACiB,iBAApBD,EAAIE,aACgB,mBAApBF,EAAI7B,eACT6B,EAAIG,sBAAsBpI,IACG,mBAAxBiI,EAAItB,iBACiB,mBAArBsB,EAAIrB,cACiB,iBAArBqB,EAAInC,cACiB,mBAArBmC,EAAIT,cACkB,mBAAtBS,EAAII,cAEhB,EAQKC,GAAU,SAAUnM,GACxB,MAAuB,mBAAT0D,GAAuB1D,aAAkB0D,CACxD,EAUK0I,GAAe,SAAUC,EAAYC,EAAaC,GACjDtH,GAAMoH,IAIXhP,EAAa4H,GAAMoH,IAAcG,IAC/BA,EAAKhB,KAAK1I,EAAWwJ,EAAaC,EAAMnE,GAAxC,GAEH,EAYKqE,GAAoB,SAAUH,GAC9B9H,IAAAA,EAAU,KAMd,GAHA4H,GAAa,yBAA0BE,EAAa,MAGhDT,GAAaS,GAEf,OADAxC,GAAawC,IACN,EAIT,MAAM5C,EAAU/J,GAAkB2M,EAAYP,UAS9C,GANAK,GAAa,sBAAuBE,EAAa,CAC/C5C,UACAgD,YAAatH,KAKbkH,EAAYJ,kBACXC,GAAQG,EAAYK,oBACrBhO,EAAW,UAAW2N,EAAYnB,YAClCxM,EAAW,UAAW2N,EAAYN,aAGlC,OADAlC,GAAawC,IACN,EAIL,IAAClH,GAAasE,IAAYzD,GAAYyD,GAAU,CAE9C,IAACzD,GAAYyD,IAAYkD,GAAsBlD,GAAU,CAC3D,GACEhE,GAAwBC,wBAAwB/G,QAChDD,EAAW+G,GAAwBC,aAAc+D,GAEjD,OAAO,EAGT,GACEhE,GAAwBC,wBAAwB6C,UAChD9C,GAAwBC,aAAa+D,GAErC,OAAO,CAEV,CAGD,GAAIzC,KAAiBG,GAAgBsC,GAAU,CACvCM,MAAAA,EAAa3F,EAAciI,IAAgBA,EAAYtC,WACvDuB,EAAanH,EAAckI,IAAgBA,EAAYf,WAEzDA,GAAAA,GAAcvB,EAAY,CAG5B,IAAK,IAAI6C,EAFUtB,EAAWpM,OAEJ,EAAG0N,GAAK,IAAKA,EACrC7C,EAAWqB,aACTnH,EAAUqH,EAAWsB,IAAI,GACzB1I,EAAemI,GAGpB,CACF,CAGD,OADAxC,GAAawC,IACN,CACR,CAGGA,OAAAA,aAAuB3I,IAAY6F,GAAqB8C,IAC1DxC,GAAawC,IACN,GAKM,aAAZ5C,GACa,YAAZA,GACY,aAAZA,IACF/K,EAAW,8BAA+B2N,EAAYnB,YAOpD5E,IAA+C,IAAzB+F,EAAYlJ,WAEpCoB,EAAU8H,EAAYN,YAEtB3O,EAAa,CAAC+D,GAAeC,GAAUC,KAAewL,IACpDtI,EAAUnG,EAAcmG,EAASsI,EAAM,IAAvC,IAGER,EAAYN,cAAgBxH,IAC9B5G,EAAUkF,EAAUI,QAAS,CAAErD,QAASyM,EAAYpI,cACpDoI,EAAYN,YAAcxH,IAK9B4H,GAAa,wBAAyBE,EAAa,OAE5C,IAtBLxC,GAAawC,IACN,EAsBV,EAWKS,GAAoB,SAAUC,EAAOC,EAAQ9M,GAEjD,GACE2G,KACY,OAAXmG,GAA8B,SAAXA,KACnB9M,KAASgD,GAAYhD,KAASkI,IAE/B,OAAO,EAOT,GACEjC,KACCF,GAAY+G,IACbtO,EAAW4C,GAAW0L,SAGjB,GAAI9G,IAAmBxH,EAAW6C,GAAWyL,SAG7C,IAAK1H,GAAa0H,IAAW/G,GAAY+G,IAE5C,KAGCL,GAAsBI,KACnBtH,GAAwBC,wBAAwB/G,QAChDD,EAAW+G,GAAwBC,aAAcqH,IAChDtH,GAAwBC,wBAAwB6C,UAC/C9C,GAAwBC,aAAaqH,MACvCtH,GAAwBK,8BAA8BnH,QACtDD,EAAW+G,GAAwBK,mBAAoBkH,IACtDvH,GAAwBK,8BAA8ByC,UACrD9C,GAAwBK,mBAAmBkH,KAGrC,OAAXA,GACCvH,GAAwBM,iCACtBN,GAAwBC,wBAAwB/G,QAChDD,EAAW+G,GAAwBC,aAAcxF,IAChDuF,GAAwBC,wBAAwB6C,UAC/C9C,GAAwBC,aAAaxF,KAK3C,OAAO,OAGJ,GAAIqH,GAAoByF,SAIxB,GACLtO,EAAW8C,GAAgBpD,EAAc8B,EAAOwB,GAAiB,WAK5D,GACO,QAAXsL,GAA+B,eAAXA,GAAsC,SAAXA,GACtC,WAAVD,GACkC,IAAlCzO,EAAc4B,EAAO,WACrBmH,GAAc0F,IAMT,GACL3G,KACC1H,EAAW+C,GAAmBrD,EAAc8B,EAAOwB,GAAiB,WAIhE,GAAIxB,EACT,OAAO,OAMT,OAAO,CACR,EAUKyM,GAAwB,SAAUlD,GACtC,OAAOA,EAAQlL,QAAQ,KAAO,CAC/B,EAYK0O,GAAsB,SAAUZ,GAEpCF,GAAa,2BAA4BE,EAAa,MAEhD,MAAAL,WAAEA,GAAeK,EAGnB,IAACL,EACH,OAGF,MAAMkB,EAAY,CAChBC,SAAU,GACVC,UAAW,GACXC,UAAU,EACVC,kBAAmBhI,IAErB,IAAI3F,EAAIqM,EAAW9M,OAGZS,KAAAA,KAAK,CACV,MAAM4N,EAAOvB,EAAWrM,IAClBwK,KAAEA,EAAFT,aAAQA,EAAcxJ,MAAOkN,GAAcG,EAC3CP,EAAStN,GAAkByK,GAE7BjK,IAAAA,EAAiB,UAATiK,EAAmBiD,EAAY5O,EAAW4O,GAUlDF,GAPJA,EAAUC,SAAWH,EACrBE,EAAUE,UAAYlN,EACtBgN,EAAUG,UAAW,EACrBH,EAAUM,mBAAgBrN,EAC1BgM,GAAa,wBAAyBE,EAAaa,GACnDhN,EAAQgN,EAAUE,UAEdF,EAAUM,cACZ,SAOF,GAHAtD,GAAiBC,EAAMkC,IAGlBa,EAAUG,SACb,SAIE,IAAChH,IAA4B3H,EAAW,OAAQwB,GAAQ,CAC1DgK,GAAiBC,EAAMkC,GACvB,QACD,CAGG/F,IACFlJ,EAAa,CAAC+D,GAAeC,GAAUC,KAAewL,IACpD3M,EAAQ9B,EAAc8B,EAAO2M,EAAM,IAAnC,IAKJ,MAAME,EAAQrN,GAAkB2M,EAAYP,UACxC,GAACgB,GAAkBC,EAAOC,EAAQ9M,GAAlC,CAgBJ,IATI4G,IAAoC,OAAXkG,GAA8B,SAAXA,IAE9C9C,GAAiBC,EAAMkC,GAGvBnM,EAAQ6G,GAA8B7G,GAKtCuE,GACwB,iBAAjB1C,GACkC,mBAAlCA,EAAa0L,iBAEpB,GAAI/D,QAGF,OAAQ3H,EAAa0L,iBAAiBV,EAAOC,IAC3C,IAAK,cACH9M,EAAQuE,EAAmBlC,WAAWrC,GACtC,MAGF,IAAK,mBACHA,EAAQuE,EAAmBjC,gBAAgBtC,GAY/C,IACEwJ,EACF2C,EAAYqB,eAAehE,EAAcS,EAAMjK,GAG/CmM,EAAY7B,aAAaL,EAAMjK,GAGjCzC,EAASoF,EAAUI,QACP,CAAZ,MAAOP,GAAK,CAlDb,CAmDF,CAGDyJ,GAAa,0BAA2BE,EAAa,KACtD,EAOKsB,GAAqB,SAArBA,EAA+BC,GAC/BC,IAAAA,EAAa,KACjB,MAAMC,EAAiBtC,GAAoBoC,GAK3C,IAFAzB,GAAa,0BAA2ByB,EAAU,MAE1CC,EAAaC,EAAeC,YAElC5B,GAAa,yBAA0B0B,EAAY,MAG/CrB,GAAkBqB,KAKlBA,EAAWtJ,mBAAmBhB,GAChCoK,EAAmBE,EAAWtJ,SAIhC0I,GAAoBY,IAItB1B,GAAa,yBAA0ByB,EAAU,KAClD,EAmRD,OAzQA/K,EAAUmL,SAAW,SAAUtD,GAAOjC,IAAAA,yDAAM,CAAA,EACtC0C,EAAO,KACP8C,EAAe,KACf5B,EAAc,KACd6B,EAAa,KAUb,GANJrG,IAAkB6C,EACd7C,KACF6C,EAAQ,eAIW,iBAAVA,IAAuBwB,GAAQxB,GAAQ,CAChD,GAA8B,mBAAnBA,EAAMzM,SAMTY,MAAAA,EAAgB,8BAJtB,GAAqB,iBADrB6L,EAAQA,EAAMzM,YAENY,MAAAA,EAAgB,kCAK3B,CAGD,IAAKgE,EAAUO,YACb,OAAOsH,EAgBT,GAZKlE,IACHgC,GAAaC,GAIf5F,EAAUI,QAAU,GAGC,iBAAVyH,IACTzD,IAAW,GAGTA,IAEEyD,GAAAA,EAAMoB,SAAU,CAClB,MAAMrC,EAAU/J,GAAkBgL,EAAMoB,UACpC,IAAC3G,GAAasE,IAAYzD,GAAYyD,GAClC5K,MAAAA,EACJ,0DAGL,OACI,GAAI6L,aAAiBjH,EAG1B0H,EAAOV,GAAc,iBACrBwD,EAAe9C,EAAK3G,cAAcO,WAAW2F,GAAO,GACtB,IAA1BuD,EAAa9K,UAA4C,SAA1B8K,EAAanC,UAGX,SAA1BmC,EAAanC,SADtBX,EAAO8C,EAKP9C,EAAKgD,YAAYF,OAEd,CAGH,IAACvH,KACAJ,KACAC,KAEuB,IAAxBmE,EAAMnM,QAAQ,KAEPkG,OAAAA,GAAsBmC,GACzBnC,EAAmBlC,WAAWmI,GAC9BA,EAOF,GAHJS,EAAOV,GAAcC,IAGhBS,EACIzE,OAAAA,GAAa,KAAOE,GAAsBlC,GAAY,EAEhE,CAGGyG,GAAQ1E,IACVoD,GAAasB,EAAKiD,YAIdC,MAAAA,EAAe7C,GAAoBvE,GAAWyD,EAAQS,GAG5D,KAAQkB,EAAcgC,EAAaN,YAE7BvB,GAAkBH,KAKlBA,EAAY9H,mBAAmBhB,GACjCoK,GAAmBtB,EAAY9H,SAIjC0I,GAAoBZ,IAItB,GAAIpF,GACF,OAAOyD,EAIT,GAAIhE,GAAY,CACd,GAAIC,GAGKwE,IAFP+C,EAAarJ,GAAuB0G,KAAKJ,EAAK3G,eAEvC2G,EAAKiD,YAEVF,EAAWC,YAAYhD,EAAKiD,iBAG9BF,EAAa/C,EAcf,OAXI7F,GAAagJ,YAAchJ,GAAaiJ,kBAQ1CL,EAAanJ,GAAWwG,KAAKlI,EAAkB6K,GAAY,IAGtDA,CACR,CAEGM,IAAAA,EAAiBjI,GAAiB4E,EAAKsD,UAAYtD,EAAKD,UAsBrDzG,OAlBL8B,IACApB,GAAa,aACbgG,EAAK3G,eACL2G,EAAK3G,cAAckK,SACnBvD,EAAK3G,cAAckK,QAAQvE,MAC3BzL,EAAWwG,EAA0BiG,EAAK3G,cAAckK,QAAQvE,QAEhEqE,EACE,aAAerD,EAAK3G,cAAckK,QAAQvE,KAAO,MAAQqE,GAIzDlI,IACFlJ,EAAa,CAAC+D,GAAeC,GAAUC,KAAewL,IACpD2B,EAAiBpQ,EAAcoQ,EAAgB3B,EAAM,IAArD,IAIGpI,GAAsBmC,GACzBnC,EAAmBlC,WAAWiM,GAC9BA,CACL,EAQD3L,EAAU8L,UAAY,WAAUlG,IAAAA,yDAAM,CAAA,EACpCD,GAAaC,GACbjC,IAAa,CACd,EAOD3D,EAAU+L,YAAc,WACtBzG,GAAS,KACT3B,IAAa,CACd,EAYD3D,EAAUgM,iBAAmB,SAAUC,EAAKvB,EAAMrN,GAE3CiI,IACHK,GAAa,CAAD,GAGd,MAAMuE,EAAQrN,GAAkBoP,GAC1B9B,EAAStN,GAAkB6N,GACjC,OAAOT,GAAkBC,EAAOC,EAAQ9M,EACzC,EASD2C,EAAUkM,QAAU,SAAU3C,EAAY4C,GACZ,mBAAjBA,IAIXhK,GAAMoH,GAAcpH,GAAMoH,IAAe,GACzCzO,EAAUqH,GAAMoH,GAAa4C,GAC9B,EAUDnM,EAAUoM,WAAa,SAAU7C,GAC/B,GAAIpH,GAAMoH,GACR,OAAO3O,EAASuH,GAAMoH,GAEzB,EAQDvJ,EAAUqM,YAAc,SAAU9C,GAC5BpH,GAAMoH,KACRpH,GAAMoH,GAAc,GAEvB,EAMDvJ,EAAUsM,eAAiB,WACzBnK,GAAQ,CAAA,CACT,EAEMnC,CACR,CAEcD"} \ No newline at end of file diff --git a/src/ui/static/js/utils/purify/src/attrs.js b/src/ui/static/js/utils/purify/src/attrs.js new file mode 100644 index 000000000..09f2a0fb2 --- /dev/null +++ b/src/ui/static/js/utils/purify/src/attrs.js @@ -0,0 +1,362 @@ +import { freeze } from './utils.js'; + +export const html = freeze([ + 'accept', + 'action', + 'align', + 'alt', + 'autocapitalize', + 'autocomplete', + 'autopictureinpicture', + 'autoplay', + 'background', + 'bgcolor', + 'border', + 'capture', + 'cellpadding', + 'cellspacing', + 'checked', + 'cite', + 'class', + 'clear', + 'color', + 'cols', + 'colspan', + 'controls', + 'controlslist', + 'coords', + 'crossorigin', + 'datetime', + 'decoding', + 'default', + 'dir', + 'disabled', + 'disablepictureinpicture', + 'disableremoteplayback', + 'download', + 'draggable', + 'enctype', + 'enterkeyhint', + 'face', + 'for', + 'headers', + 'height', + 'hidden', + 'high', + 'href', + 'hreflang', + 'id', + 'inputmode', + 'integrity', + 'ismap', + 'kind', + 'label', + 'lang', + 'list', + 'loading', + 'loop', + 'low', + 'max', + 'maxlength', + 'media', + 'method', + 'min', + 'minlength', + 'multiple', + 'muted', + 'name', + 'nonce', + 'noshade', + 'novalidate', + 'nowrap', + 'open', + 'optimum', + 'pattern', + 'placeholder', + 'playsinline', + 'poster', + 'preload', + 'pubdate', + 'radiogroup', + 'readonly', + 'rel', + 'required', + 'rev', + 'reversed', + 'role', + 'rows', + 'rowspan', + 'spellcheck', + 'scope', + 'selected', + 'shape', + 'size', + 'sizes', + 'span', + 'srclang', + 'start', + 'src', + 'srcset', + 'step', + 'style', + 'summary', + 'tabindex', + 'title', + 'translate', + 'type', + 'usemap', + 'valign', + 'value', + 'width', + 'xmlns', + 'slot', +]); + +export const svg = freeze([ + 'accent-height', + 'accumulate', + 'additive', + 'alignment-baseline', + 'ascent', + 'attributename', + 'attributetype', + 'azimuth', + 'basefrequency', + 'baseline-shift', + 'begin', + 'bias', + 'by', + 'class', + 'clip', + 'clippathunits', + 'clip-path', + 'clip-rule', + 'color', + 'color-interpolation', + 'color-interpolation-filters', + 'color-profile', + 'color-rendering', + 'cx', + 'cy', + 'd', + 'dx', + 'dy', + 'diffuseconstant', + 'direction', + 'display', + 'divisor', + 'dur', + 'edgemode', + 'elevation', + 'end', + 'fill', + 'fill-opacity', + 'fill-rule', + 'filter', + 'filterunits', + 'flood-color', + 'flood-opacity', + 'font-family', + 'font-size', + 'font-size-adjust', + 'font-stretch', + 'font-style', + 'font-variant', + 'font-weight', + 'fx', + 'fy', + 'g1', + 'g2', + 'glyph-name', + 'glyphref', + 'gradientunits', + 'gradienttransform', + 'height', + 'href', + 'id', + 'image-rendering', + 'in', + 'in2', + 'k', + 'k1', + 'k2', + 'k3', + 'k4', + 'kerning', + 'keypoints', + 'keysplines', + 'keytimes', + 'lang', + 'lengthadjust', + 'letter-spacing', + 'kernelmatrix', + 'kernelunitlength', + 'lighting-color', + 'local', + 'marker-end', + 'marker-mid', + 'marker-start', + 'markerheight', + 'markerunits', + 'markerwidth', + 'maskcontentunits', + 'maskunits', + 'max', + 'mask', + 'media', + 'method', + 'mode', + 'min', + 'name', + 'numoctaves', + 'offset', + 'operator', + 'opacity', + 'order', + 'orient', + 'orientation', + 'origin', + 'overflow', + 'paint-order', + 'path', + 'pathlength', + 'patterncontentunits', + 'patterntransform', + 'patternunits', + 'points', + 'preservealpha', + 'preserveaspectratio', + 'primitiveunits', + 'r', + 'rx', + 'ry', + 'radius', + 'refx', + 'refy', + 'repeatcount', + 'repeatdur', + 'restart', + 'result', + 'rotate', + 'scale', + 'seed', + 'shape-rendering', + 'specularconstant', + 'specularexponent', + 'spreadmethod', + 'startoffset', + 'stddeviation', + 'stitchtiles', + 'stop-color', + 'stop-opacity', + 'stroke-dasharray', + 'stroke-dashoffset', + 'stroke-linecap', + 'stroke-linejoin', + 'stroke-miterlimit', + 'stroke-opacity', + 'stroke', + 'stroke-width', + 'style', + 'surfacescale', + 'systemlanguage', + 'tabindex', + 'targetx', + 'targety', + 'transform', + 'transform-origin', + 'text-anchor', + 'text-decoration', + 'text-rendering', + 'textlength', + 'type', + 'u1', + 'u2', + 'unicode', + 'values', + 'viewbox', + 'visibility', + 'version', + 'vert-adv-y', + 'vert-origin-x', + 'vert-origin-y', + 'width', + 'word-spacing', + 'wrap', + 'writing-mode', + 'xchannelselector', + 'ychannelselector', + 'x', + 'x1', + 'x2', + 'xmlns', + 'y', + 'y1', + 'y2', + 'z', + 'zoomandpan', +]); + +export const mathMl = freeze([ + 'accent', + 'accentunder', + 'align', + 'bevelled', + 'close', + 'columnsalign', + 'columnlines', + 'columnspan', + 'denomalign', + 'depth', + 'dir', + 'display', + 'displaystyle', + 'encoding', + 'fence', + 'frame', + 'height', + 'href', + 'id', + 'largeop', + 'length', + 'linethickness', + 'lspace', + 'lquote', + 'mathbackground', + 'mathcolor', + 'mathsize', + 'mathvariant', + 'maxsize', + 'minsize', + 'movablelimits', + 'notation', + 'numalign', + 'open', + 'rowalign', + 'rowlines', + 'rowspacing', + 'rowspan', + 'rspace', + 'rquote', + 'scriptlevel', + 'scriptminsize', + 'scriptsizemultiplier', + 'selection', + 'separator', + 'separators', + 'stretchy', + 'subscriptshift', + 'supscriptshift', + 'symmetric', + 'voffset', + 'width', + 'xmlns', +]); + +export const xml = freeze([ + 'xlink:href', + 'xml:id', + 'xlink:title', + 'xml:space', + 'xmlns:xlink', +]); diff --git a/src/ui/static/js/utils/purify/src/purify.js b/src/ui/static/js/utils/purify/src/purify.js new file mode 100644 index 000000000..f6511db6d --- /dev/null +++ b/src/ui/static/js/utils/purify/src/purify.js @@ -0,0 +1,1637 @@ +import * as TAGS from './tags.js'; +import * as ATTRS from './attrs.js'; +import * as EXPRESSIONS from './regexp.js'; +import { + addToSet, + clone, + entries, + freeze, + arrayForEach, + arrayPop, + arrayPush, + stringMatch, + stringReplace, + stringToLowerCase, + stringToString, + stringIndexOf, + stringTrim, + regExpTest, + typeErrorCreate, + lookupGetter, + create, +} from './utils.js'; + +const getGlobal = function () { + return typeof window === 'undefined' ? null : window; +}; + +/** + * Creates a no-op policy for internal use only. + * Don't export this function outside this module! + * @param {?TrustedTypePolicyFactory} trustedTypes The policy factory. + * @param {HTMLScriptElement} purifyHostElement The Script element used to load DOMPurify (to determine policy name suffix). + * @return {?TrustedTypePolicy} The policy created (or null, if Trusted Types + * are not supported or creating the policy failed). + */ +const _createTrustedTypesPolicy = function (trustedTypes, purifyHostElement) { + if ( + typeof trustedTypes !== 'object' || + typeof trustedTypes.createPolicy !== 'function' + ) { + return null; + } + + // Allow the callers to control the unique policy name + // by adding a data-tt-policy-suffix to the script element with the DOMPurify. + // Policy creation with duplicate names throws in Trusted Types. + let suffix = null; + const ATTR_NAME = 'data-tt-policy-suffix'; + if (purifyHostElement && purifyHostElement.hasAttribute(ATTR_NAME)) { + suffix = purifyHostElement.getAttribute(ATTR_NAME); + } + + const policyName = 'dompurify' + (suffix ? '#' + suffix : ''); + + try { + return trustedTypes.createPolicy(policyName, { + createHTML(html) { + return html; + }, + createScriptURL(scriptUrl) { + return scriptUrl; + }, + }); + } catch (_) { + // Policy creation failed (most likely another DOMPurify script has + // already run). Skip creating the policy, as this will only cause errors + // if TT are enforced. + console.warn( + 'TrustedTypes policy ' + policyName + ' could not be created.' + ); + return null; + } +}; + +function createDOMPurify(window = getGlobal()) { + const DOMPurify = (root) => createDOMPurify(root); + + /** + * Version label, exposed for easier checks + * if DOMPurify is up to date or not + */ + DOMPurify.version = VERSION; + + /** + * Array of elements that DOMPurify removed during sanitation. + * Empty if nothing was removed. + */ + DOMPurify.removed = []; + + if (!window || !window.document || window.document.nodeType !== 9) { + // Not running in a browser, provide a factory function + // so that you can pass your own Window + DOMPurify.isSupported = false; + + return DOMPurify; + } + + let { document } = window; + + const originalDocument = document; + const currentScript = originalDocument.currentScript; + const { + DocumentFragment, + HTMLTemplateElement, + Node, + Element, + NodeFilter, + NamedNodeMap = window.NamedNodeMap || window.MozNamedAttrMap, + HTMLFormElement, + DOMParser, + trustedTypes, + } = window; + + const ElementPrototype = Element.prototype; + + const cloneNode = lookupGetter(ElementPrototype, 'cloneNode'); + const getNextSibling = lookupGetter(ElementPrototype, 'nextSibling'); + const getChildNodes = lookupGetter(ElementPrototype, 'childNodes'); + const getParentNode = lookupGetter(ElementPrototype, 'parentNode'); + + // As per issue #47, the web-components registry is inherited by a + // new document created via createHTMLDocument. As per the spec + // (http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries) + // a new empty registry is used when creating a template contents owner + // document, so we use that as our parent document to ensure nothing + // is inherited. + if (typeof HTMLTemplateElement === 'function') { + const template = document.createElement('template'); + if (template.content && template.content.ownerDocument) { + document = template.content.ownerDocument; + } + } + + let trustedTypesPolicy; + let emptyHTML = ''; + + const { + implementation, + createNodeIterator, + createDocumentFragment, + getElementsByTagName, + } = document; + const { importNode } = originalDocument; + + let hooks = {}; + + /** + * Expose whether this browser supports running the full DOMPurify. + */ + DOMPurify.isSupported = + typeof entries === 'function' && + typeof getParentNode === 'function' && + implementation && + implementation.createHTMLDocument !== undefined; + + const { + MUSTACHE_EXPR, + ERB_EXPR, + TMPLIT_EXPR, + DATA_ATTR, + ARIA_ATTR, + IS_SCRIPT_OR_DATA, + ATTR_WHITESPACE, + } = EXPRESSIONS; + + let { IS_ALLOWED_URI } = EXPRESSIONS; + + /** + * We consider the elements and attributes below to be safe. Ideally + * don't add any new ones but feel free to remove unwanted ones. + */ + + /* allowed element names */ + let ALLOWED_TAGS = null; + const DEFAULT_ALLOWED_TAGS = addToSet({}, [ + ...TAGS.html, + ...TAGS.svg, + ...TAGS.svgFilters, + ...TAGS.mathMl, + ...TAGS.text, + ]); + + /* Allowed attribute names */ + let ALLOWED_ATTR = null; + const DEFAULT_ALLOWED_ATTR = addToSet({}, [ + ...ATTRS.html, + ...ATTRS.svg, + ...ATTRS.mathMl, + ...ATTRS.xml, + ]); + + /* + * Configure how DOMPUrify should handle custom elements and their attributes as well as customized built-in elements. + * @property {RegExp|Function|null} tagNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any custom elements) + * @property {RegExp|Function|null} attributeNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any attributes not on the allow list) + * @property {boolean} allowCustomizedBuiltInElements allow custom elements derived from built-ins if they pass CUSTOM_ELEMENT_HANDLING.tagNameCheck. Default: `false`. + */ + let CUSTOM_ELEMENT_HANDLING = Object.seal( + create(null, { + tagNameCheck: { + writable: true, + configurable: false, + enumerable: true, + value: null, + }, + attributeNameCheck: { + writable: true, + configurable: false, + enumerable: true, + value: null, + }, + allowCustomizedBuiltInElements: { + writable: true, + configurable: false, + enumerable: true, + value: false, + }, + }) + ); + + /* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */ + let FORBID_TAGS = null; + + /* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */ + let FORBID_ATTR = null; + + /* Decide if ARIA attributes are okay */ + let ALLOW_ARIA_ATTR = true; + + /* Decide if custom data attributes are okay */ + let ALLOW_DATA_ATTR = true; + + /* Decide if unknown protocols are okay */ + let ALLOW_UNKNOWN_PROTOCOLS = false; + + /* Decide if self-closing tags in attributes are allowed. + * Usually removed due to a mXSS issue in jQuery 3.0 */ + let ALLOW_SELF_CLOSE_IN_ATTR = true; + + /* Output should be safe for common template engines. + * This means, DOMPurify removes data attributes, mustaches and ERB + */ + let SAFE_FOR_TEMPLATES = false; + + /* Decide if document with ... should be returned */ + let WHOLE_DOCUMENT = false; + + /* Track whether config is already set on this instance of DOMPurify. */ + let SET_CONFIG = false; + + /* Decide if all elements (e.g. style, script) must be children of + * document.body. By default, browsers might move them to document.head */ + let FORCE_BODY = false; + + /* Decide if a DOM `HTMLBodyElement` should be returned, instead of a html + * string (or a TrustedHTML object if Trusted Types are supported). + * If `WHOLE_DOCUMENT` is enabled a `HTMLHtmlElement` will be returned instead + */ + let RETURN_DOM = false; + + /* Decide if a DOM `DocumentFragment` should be returned, instead of a html + * string (or a TrustedHTML object if Trusted Types are supported) */ + let RETURN_DOM_FRAGMENT = false; + + /* Try to return a Trusted Type object instead of a string, return a string in + * case Trusted Types are not supported */ + let RETURN_TRUSTED_TYPE = false; + + /* Output should be free from DOM clobbering attacks? + * This sanitizes markups named with colliding, clobberable built-in DOM APIs. + */ + let SANITIZE_DOM = true; + + /* Achieve full DOM Clobbering protection by isolating the namespace of named + * properties and JS variables, mitigating attacks that abuse the HTML/DOM spec rules. + * + * HTML/DOM spec rules that enable DOM Clobbering: + * - Named Access on Window (§7.3.3) + * - DOM Tree Accessors (§3.1.5) + * - Form Element Parent-Child Relations (§4.10.3) + * - Iframe srcdoc / Nested WindowProxies (§4.8.5) + * - HTMLCollection (§4.2.10.2) + * + * Namespace isolation is implemented by prefixing `id` and `name` attributes + * with a constant string, i.e., `user-content-` + */ + let SANITIZE_NAMED_PROPS = false; + const SANITIZE_NAMED_PROPS_PREFIX = 'user-content-'; + + /* Keep element content when removing element? */ + let KEEP_CONTENT = true; + + /* If a `Node` is passed to sanitize(), then performs sanitization in-place instead + * of importing it into a new Document and returning a sanitized copy */ + let IN_PLACE = false; + + /* Allow usage of profiles like html, svg and mathMl */ + let USE_PROFILES = {}; + + /* Tags to ignore content of when KEEP_CONTENT is true */ + let FORBID_CONTENTS = null; + const DEFAULT_FORBID_CONTENTS = addToSet({}, [ + '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', + ]); + + /* Tags that are safe for data: URIs */ + let DATA_URI_TAGS = null; + const DEFAULT_DATA_URI_TAGS = addToSet({}, [ + 'audio', + 'video', + 'img', + 'source', + 'image', + 'track', + ]); + + /* Attributes safe for values like "javascript:" */ + let URI_SAFE_ATTRIBUTES = null; + const DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, [ + 'alt', + 'class', + 'for', + 'id', + 'label', + 'name', + 'pattern', + 'placeholder', + 'role', + 'summary', + 'title', + 'value', + 'style', + 'xmlns', + ]); + + const MATHML_NAMESPACE = 'http://www.w3.org/1998/Math/MathML'; + const SVG_NAMESPACE = 'http://www.w3.org/2000/svg'; + const HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml'; + /* Document namespace */ + let NAMESPACE = HTML_NAMESPACE; + let IS_EMPTY_INPUT = false; + + /* Allowed XHTML+XML namespaces */ + let ALLOWED_NAMESPACES = null; + const DEFAULT_ALLOWED_NAMESPACES = addToSet( + {}, + [MATHML_NAMESPACE, SVG_NAMESPACE, HTML_NAMESPACE], + stringToString + ); + + /* Parsing of strict XHTML documents */ + let PARSER_MEDIA_TYPE = null; + const SUPPORTED_PARSER_MEDIA_TYPES = ['application/xhtml+xml', 'text/html']; + const DEFAULT_PARSER_MEDIA_TYPE = 'text/html'; + let transformCaseFunc = null; + + /* Keep a reference to config to pass to hooks */ + let CONFIG = null; + + /* Ideally, do not touch anything below this line */ + /* ______________________________________________ */ + + const formElement = document.createElement('form'); + + const isRegexOrFunction = function (testValue) { + return testValue instanceof RegExp || testValue instanceof Function; + }; + + /** + * _parseConfig + * + * @param {Object} cfg optional config literal + */ + // eslint-disable-next-line complexity + const _parseConfig = function (cfg = {}) { + if (CONFIG && CONFIG === cfg) { + return; + } + + /* Shield configuration object from tampering */ + if (!cfg || typeof cfg !== 'object') { + cfg = {}; + } + + /* Shield configuration object from prototype pollution */ + cfg = clone(cfg); + + PARSER_MEDIA_TYPE = + // eslint-disable-next-line unicorn/prefer-includes + SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 + ? (PARSER_MEDIA_TYPE = DEFAULT_PARSER_MEDIA_TYPE) + : (PARSER_MEDIA_TYPE = cfg.PARSER_MEDIA_TYPE); + + // HTML tags and attributes are not case-sensitive, converting to lowercase. Keeping XHTML as is. + transformCaseFunc = + PARSER_MEDIA_TYPE === 'application/xhtml+xml' + ? stringToString + : stringToLowerCase; + + /* Set configuration parameters */ + ALLOWED_TAGS = + 'ALLOWED_TAGS' in cfg + ? addToSet({}, cfg.ALLOWED_TAGS, transformCaseFunc) + : DEFAULT_ALLOWED_TAGS; + ALLOWED_ATTR = + 'ALLOWED_ATTR' in cfg + ? addToSet({}, cfg.ALLOWED_ATTR, transformCaseFunc) + : DEFAULT_ALLOWED_ATTR; + ALLOWED_NAMESPACES = + 'ALLOWED_NAMESPACES' in cfg + ? addToSet({}, cfg.ALLOWED_NAMESPACES, stringToString) + : DEFAULT_ALLOWED_NAMESPACES; + URI_SAFE_ATTRIBUTES = + 'ADD_URI_SAFE_ATTR' in cfg + ? addToSet( + clone(DEFAULT_URI_SAFE_ATTRIBUTES), // eslint-disable-line indent + cfg.ADD_URI_SAFE_ATTR, // eslint-disable-line indent + transformCaseFunc // eslint-disable-line indent + ) // eslint-disable-line indent + : DEFAULT_URI_SAFE_ATTRIBUTES; + DATA_URI_TAGS = + 'ADD_DATA_URI_TAGS' in cfg + ? addToSet( + clone(DEFAULT_DATA_URI_TAGS), // eslint-disable-line indent + cfg.ADD_DATA_URI_TAGS, // eslint-disable-line indent + transformCaseFunc // eslint-disable-line indent + ) // eslint-disable-line indent + : DEFAULT_DATA_URI_TAGS; + FORBID_CONTENTS = + 'FORBID_CONTENTS' in cfg + ? addToSet({}, cfg.FORBID_CONTENTS, transformCaseFunc) + : DEFAULT_FORBID_CONTENTS; + FORBID_TAGS = + 'FORBID_TAGS' in cfg + ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc) + : {}; + FORBID_ATTR = + 'FORBID_ATTR' in cfg + ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc) + : {}; + USE_PROFILES = 'USE_PROFILES' in cfg ? cfg.USE_PROFILES : false; + ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true + ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true + ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false + ALLOW_SELF_CLOSE_IN_ATTR = cfg.ALLOW_SELF_CLOSE_IN_ATTR !== false; // Default true + SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; // Default false + WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false + RETURN_DOM = cfg.RETURN_DOM || false; // Default false + RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false + RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; // Default false + FORCE_BODY = cfg.FORCE_BODY || false; // Default false + SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true + SANITIZE_NAMED_PROPS = cfg.SANITIZE_NAMED_PROPS || false; // Default false + KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true + IN_PLACE = cfg.IN_PLACE || false; // Default false + IS_ALLOWED_URI = cfg.ALLOWED_URI_REGEXP || EXPRESSIONS.IS_ALLOWED_URI; + NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE; + CUSTOM_ELEMENT_HANDLING = cfg.CUSTOM_ELEMENT_HANDLING || {}; + if ( + cfg.CUSTOM_ELEMENT_HANDLING && + isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck) + ) { + CUSTOM_ELEMENT_HANDLING.tagNameCheck = + cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck; + } + + if ( + cfg.CUSTOM_ELEMENT_HANDLING && + isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck) + ) { + CUSTOM_ELEMENT_HANDLING.attributeNameCheck = + cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck; + } + + if ( + cfg.CUSTOM_ELEMENT_HANDLING && + typeof cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements === + 'boolean' + ) { + CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements = + cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements; + } + + if (SAFE_FOR_TEMPLATES) { + ALLOW_DATA_ATTR = false; + } + + if (RETURN_DOM_FRAGMENT) { + RETURN_DOM = true; + } + + /* Parse profile info */ + if (USE_PROFILES) { + ALLOWED_TAGS = addToSet({}, [...TAGS.text]); + ALLOWED_ATTR = []; + if (USE_PROFILES.html === true) { + addToSet(ALLOWED_TAGS, TAGS.html); + addToSet(ALLOWED_ATTR, ATTRS.html); + } + + if (USE_PROFILES.svg === true) { + addToSet(ALLOWED_TAGS, TAGS.svg); + addToSet(ALLOWED_ATTR, ATTRS.svg); + addToSet(ALLOWED_ATTR, ATTRS.xml); + } + + if (USE_PROFILES.svgFilters === true) { + addToSet(ALLOWED_TAGS, TAGS.svgFilters); + addToSet(ALLOWED_ATTR, ATTRS.svg); + addToSet(ALLOWED_ATTR, ATTRS.xml); + } + + if (USE_PROFILES.mathMl === true) { + addToSet(ALLOWED_TAGS, TAGS.mathMl); + addToSet(ALLOWED_ATTR, ATTRS.mathMl); + addToSet(ALLOWED_ATTR, ATTRS.xml); + } + } + + /* Merge configuration parameters */ + if (cfg.ADD_TAGS) { + if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) { + ALLOWED_TAGS = clone(ALLOWED_TAGS); + } + + addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc); + } + + if (cfg.ADD_ATTR) { + if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) { + ALLOWED_ATTR = clone(ALLOWED_ATTR); + } + + addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc); + } + + if (cfg.ADD_URI_SAFE_ATTR) { + addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc); + } + + if (cfg.FORBID_CONTENTS) { + if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) { + FORBID_CONTENTS = clone(FORBID_CONTENTS); + } + + addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc); + } + + /* Add #text in case KEEP_CONTENT is set to true */ + if (KEEP_CONTENT) { + ALLOWED_TAGS['#text'] = true; + } + + /* Add html, head and body to ALLOWED_TAGS in case WHOLE_DOCUMENT is true */ + if (WHOLE_DOCUMENT) { + addToSet(ALLOWED_TAGS, ['html', 'head', 'body']); + } + + /* Add tbody to ALLOWED_TAGS in case tables are permitted, see #286, #365 */ + if (ALLOWED_TAGS.table) { + addToSet(ALLOWED_TAGS, ['tbody']); + delete FORBID_TAGS.tbody; + } + + if (cfg.TRUSTED_TYPES_POLICY) { + if (typeof cfg.TRUSTED_TYPES_POLICY.createHTML !== 'function') { + throw typeErrorCreate( + 'TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.' + ); + } + + if (typeof cfg.TRUSTED_TYPES_POLICY.createScriptURL !== 'function') { + throw typeErrorCreate( + 'TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.' + ); + } + + // Overwrite existing TrustedTypes policy. + trustedTypesPolicy = cfg.TRUSTED_TYPES_POLICY; + + // Sign local variables required by `sanitize`. + emptyHTML = trustedTypesPolicy.createHTML(''); + } else { + // Uninitialized policy, attempt to initialize the internal dompurify policy. + if (trustedTypesPolicy === undefined) { + trustedTypesPolicy = _createTrustedTypesPolicy( + trustedTypes, + currentScript + ); + } + + // If creating the internal policy succeeded sign internal variables. + if (trustedTypesPolicy !== null && typeof emptyHTML === 'string') { + emptyHTML = trustedTypesPolicy.createHTML(''); + } + } + + // Prevent further manipulation of configuration. + // Not available in IE8, Safari 5, etc. + if (freeze) { + freeze(cfg); + } + + CONFIG = cfg; + }; + + const MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, [ + 'mi', + 'mo', + 'mn', + 'ms', + 'mtext', + ]); + + const HTML_INTEGRATION_POINTS = addToSet({}, [ + 'foreignobject', + 'desc', + 'title', + 'annotation-xml', + ]); + + // Certain elements are allowed in both SVG and HTML + // namespace. We need to specify them explicitly + // so that they don't get erroneously deleted from + // HTML namespace. + const COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, [ + 'title', + 'style', + 'font', + 'a', + 'script', + ]); + + /* Keep track of all possible SVG and MathML tags + * so that we can perform the namespace checks + * correctly. */ + const ALL_SVG_TAGS = addToSet({}, TAGS.svg); + addToSet(ALL_SVG_TAGS, TAGS.svgFilters); + addToSet(ALL_SVG_TAGS, TAGS.svgDisallowed); + + const ALL_MATHML_TAGS = addToSet({}, TAGS.mathMl); + addToSet(ALL_MATHML_TAGS, TAGS.mathMlDisallowed); + + /** + * @param {Element} element a DOM element whose namespace is being checked + * @returns {boolean} Return false if the element has a + * namespace that a spec-compliant parser would never + * return. Return true otherwise. + */ + const _checkValidNamespace = function (element) { + let parent = getParentNode(element); + + // In JSDOM, if we're inside shadow DOM, then parentNode + // can be null. We just simulate parent in this case. + if (!parent || !parent.tagName) { + parent = { + namespaceURI: NAMESPACE, + tagName: 'template', + }; + } + + const tagName = stringToLowerCase(element.tagName); + const parentTagName = stringToLowerCase(parent.tagName); + + if (!ALLOWED_NAMESPACES[element.namespaceURI]) { + return false; + } + + if (element.namespaceURI === SVG_NAMESPACE) { + // The only way to switch from HTML namespace to SVG + // is via . If it happens via any other tag, then + // it should be killed. + if (parent.namespaceURI === HTML_NAMESPACE) { + return tagName === 'svg'; + } + + // The only way to switch from MathML to SVG is via` + // svg if parent is either or MathML + // text integration points. + if (parent.namespaceURI === MATHML_NAMESPACE) { + return ( + tagName === 'svg' && + (parentTagName === 'annotation-xml' || + MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) + ); + } + + // We only allow elements that are defined in SVG + // spec. All others are disallowed in SVG namespace. + return Boolean(ALL_SVG_TAGS[tagName]); + } + + if (element.namespaceURI === MATHML_NAMESPACE) { + // The only way to switch from HTML namespace to MathML + // is via . If it happens via any other tag, then + // it should be killed. + if (parent.namespaceURI === HTML_NAMESPACE) { + return tagName === 'math'; + } + + // The only way to switch from SVG to MathML is via + // and HTML integration points + if (parent.namespaceURI === SVG_NAMESPACE) { + return tagName === 'math' && HTML_INTEGRATION_POINTS[parentTagName]; + } + + // We only allow elements that are defined in MathML + // spec. All others are disallowed in MathML namespace. + return Boolean(ALL_MATHML_TAGS[tagName]); + } + + if (element.namespaceURI === HTML_NAMESPACE) { + // The only way to switch from SVG to HTML is via + // HTML integration points, and from MathML to HTML + // is via MathML text integration points + if ( + parent.namespaceURI === SVG_NAMESPACE && + !HTML_INTEGRATION_POINTS[parentTagName] + ) { + return false; + } + + if ( + parent.namespaceURI === MATHML_NAMESPACE && + !MATHML_TEXT_INTEGRATION_POINTS[parentTagName] + ) { + return false; + } + + // We disallow tags that are specific for MathML + // or SVG and should never appear in HTML namespace + return ( + !ALL_MATHML_TAGS[tagName] && + (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName]) + ); + } + + // For XHTML and XML documents that support custom namespaces + if ( + PARSER_MEDIA_TYPE === 'application/xhtml+xml' && + ALLOWED_NAMESPACES[element.namespaceURI] + ) { + return true; + } + + // The code should never reach this place (this means + // that the element somehow got namespace that is not + // HTML, SVG, MathML or allowed via ALLOWED_NAMESPACES). + // Return false just in case. + return false; + }; + + /** + * _forceRemove + * + * @param {Node} node a DOM node + */ + const _forceRemove = function (node) { + arrayPush(DOMPurify.removed, { element: node }); + try { + // eslint-disable-next-line unicorn/prefer-dom-node-remove + node.parentNode.removeChild(node); + } catch (_) { + node.remove(); + } + }; + + /** + * _removeAttribute + * + * @param {String} name an Attribute name + * @param {Node} node a DOM node + */ + const _removeAttribute = function (name, node) { + try { + arrayPush(DOMPurify.removed, { + attribute: node.getAttributeNode(name), + from: node, + }); + } catch (_) { + arrayPush(DOMPurify.removed, { + attribute: null, + from: node, + }); + } + + node.removeAttribute(name); + + // We void attribute values for unremovable "is"" attributes + if (name === 'is' && !ALLOWED_ATTR[name]) { + if (RETURN_DOM || RETURN_DOM_FRAGMENT) { + try { + _forceRemove(node); + } catch (_) {} + } else { + try { + node.setAttribute(name, ''); + } catch (_) {} + } + } + }; + + /** + * _initDocument + * + * @param {String} dirty a string of dirty markup + * @return {Document} a DOM, filled with the dirty markup + */ + const _initDocument = function (dirty) { + /* Create a HTML document */ + let doc = null; + let leadingWhitespace = null; + + if (FORCE_BODY) { + dirty = '' + dirty; + } else { + /* If FORCE_BODY isn't used, leading whitespace needs to be preserved manually */ + const matches = stringMatch(dirty, /^[\r\n\t ]+/); + leadingWhitespace = matches && matches[0]; + } + + if ( + PARSER_MEDIA_TYPE === 'application/xhtml+xml' && + NAMESPACE === HTML_NAMESPACE + ) { + // Root of XHTML doc must contain xmlns declaration (see https://www.w3.org/TR/xhtml1/normative.html#strict) + dirty = + '' + + dirty + + ''; + } + + const dirtyPayload = trustedTypesPolicy + ? trustedTypesPolicy.createHTML(dirty) + : dirty; + /* + * Use the DOMParser API by default, fallback later if needs be + * DOMParser not work for svg when has multiple root element. + */ + if (NAMESPACE === HTML_NAMESPACE) { + try { + doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE); + } catch (_) {} + } + + /* Use createHTMLDocument in case DOMParser is not available */ + if (!doc || !doc.documentElement) { + doc = implementation.createDocument(NAMESPACE, 'template', null); + try { + doc.documentElement.innerHTML = IS_EMPTY_INPUT + ? emptyHTML + : dirtyPayload; + } catch (_) { + // Syntax error if dirtyPayload is invalid xml + } + } + + const body = doc.body || doc.documentElement; + + if (dirty && leadingWhitespace) { + body.insertBefore( + document.createTextNode(leadingWhitespace), + body.childNodes[0] || null + ); + } + + /* Work on whole document or just its body */ + if (NAMESPACE === HTML_NAMESPACE) { + return getElementsByTagName.call( + doc, + WHOLE_DOCUMENT ? 'html' : 'body' + )[0]; + } + + return WHOLE_DOCUMENT ? doc.documentElement : body; + }; + + /** + * Creates a NodeIterator object that you can use to traverse filtered lists of nodes or elements in a document. + * + * @param {Node} root The root element or node to start traversing on. + * @return {NodeIterator} The created NodeIterator + */ + const _createNodeIterator = function (root) { + return createNodeIterator.call( + root.ownerDocument || root, + root, + // eslint-disable-next-line no-bitwise + NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT, + null + ); + }; + + /** + * _isClobbered + * + * @param {Node} elm element to check for clobbering attacks + * @return {Boolean} true if clobbered, false if safe + */ + const _isClobbered = function (elm) { + return ( + elm instanceof HTMLFormElement && + (typeof elm.nodeName !== 'string' || + typeof elm.textContent !== 'string' || + typeof elm.removeChild !== 'function' || + !(elm.attributes instanceof NamedNodeMap) || + typeof elm.removeAttribute !== 'function' || + typeof elm.setAttribute !== 'function' || + typeof elm.namespaceURI !== 'string' || + typeof elm.insertBefore !== 'function' || + typeof elm.hasChildNodes !== 'function') + ); + }; + + /** + * Checks whether the given object is a DOM node. + * + * @param {Node} object object to check whether it's a DOM node + * @return {Boolean} true is object is a DOM node + */ + const _isNode = function (object) { + return typeof Node === 'function' && object instanceof Node; + }; + + /** + * _executeHook + * Execute user configurable hooks + * + * @param {String} entryPoint Name of the hook's entry point + * @param {Node} currentNode node to work on with the hook + * @param {Object} data additional hook parameters + */ + const _executeHook = function (entryPoint, currentNode, data) { + if (!hooks[entryPoint]) { + return; + } + + arrayForEach(hooks[entryPoint], (hook) => { + hook.call(DOMPurify, currentNode, data, CONFIG); + }); + }; + + /** + * _sanitizeElements + * + * @protect nodeName + * @protect textContent + * @protect removeChild + * + * @param {Node} currentNode to check for permission to exist + * @return {Boolean} true if node was killed, false if left alive + */ + const _sanitizeElements = function (currentNode) { + let content = null; + + /* Execute a hook if present */ + _executeHook('beforeSanitizeElements', currentNode, null); + + /* Check if element is clobbered or can clobber */ + if (_isClobbered(currentNode)) { + _forceRemove(currentNode); + return true; + } + + /* Now let's check the element's type and name */ + const tagName = transformCaseFunc(currentNode.nodeName); + + /* Execute a hook if present */ + _executeHook('uponSanitizeElement', currentNode, { + tagName, + allowedTags: ALLOWED_TAGS, + }); + + /* Detect mXSS attempts abusing namespace confusion */ + if ( + currentNode.hasChildNodes() && + !_isNode(currentNode.firstElementChild) && + regExpTest(/<[/\w]/g, currentNode.innerHTML) && + regExpTest(/<[/\w]/g, currentNode.textContent) + ) { + _forceRemove(currentNode); + return true; + } + + /* Remove element if anything forbids its presence */ + if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) { + /* Check if we have a custom element to handle */ + if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) { + if ( + CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && + regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName) + ) { + return false; + } + + if ( + CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && + CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName) + ) { + return false; + } + } + + /* Keep content except for bad-listed elements */ + if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) { + const parentNode = getParentNode(currentNode) || currentNode.parentNode; + const childNodes = getChildNodes(currentNode) || currentNode.childNodes; + + if (childNodes && parentNode) { + const childCount = childNodes.length; + + for (let i = childCount - 1; i >= 0; --i) { + parentNode.insertBefore( + cloneNode(childNodes[i], true), + getNextSibling(currentNode) + ); + } + } + } + + _forceRemove(currentNode); + return true; + } + + /* Check whether element has a valid namespace */ + if (currentNode instanceof Element && !_checkValidNamespace(currentNode)) { + _forceRemove(currentNode); + return true; + } + + /* Make sure that older browsers don't get fallback-tag mXSS */ + if ( + (tagName === 'noscript' || + tagName === 'noembed' || + tagName === 'noframes') && + regExpTest(/<\/no(script|embed|frames)/i, currentNode.innerHTML) + ) { + _forceRemove(currentNode); + return true; + } + + /* Sanitize element content to be template-safe */ + if (SAFE_FOR_TEMPLATES && currentNode.nodeType === 3) { + /* Get the element's text content */ + content = currentNode.textContent; + + arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], (expr) => { + content = stringReplace(content, expr, ' '); + }); + + if (currentNode.textContent !== content) { + arrayPush(DOMPurify.removed, { element: currentNode.cloneNode() }); + currentNode.textContent = content; + } + } + + /* Execute a hook if present */ + _executeHook('afterSanitizeElements', currentNode, null); + + return false; + }; + + /** + * _isValidAttribute + * + * @param {string} lcTag Lowercase tag name of containing element. + * @param {string} lcName Lowercase attribute name. + * @param {string} value Attribute value. + * @return {Boolean} Returns true if `value` is valid, otherwise false. + */ + // eslint-disable-next-line complexity + const _isValidAttribute = function (lcTag, lcName, value) { + /* Make sure attribute cannot clobber */ + if ( + SANITIZE_DOM && + (lcName === 'id' || lcName === 'name') && + (value in document || value in formElement) + ) { + return false; + } + + /* Allow valid data-* attributes: At least one character after "-" + (https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes) + XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804) + We don't need to check the value; it's always URI safe. */ + if ( + ALLOW_DATA_ATTR && + !FORBID_ATTR[lcName] && + regExpTest(DATA_ATTR, lcName) + ) { + // This attribute is safe + } else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR, lcName)) { + // This attribute is safe + /* Otherwise, check the name is permitted */ + } else if (!ALLOWED_ATTR[lcName] || FORBID_ATTR[lcName]) { + if ( + // First condition does a very basic check if a) it's basically a valid custom element tagname AND + // b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck + // and c) if the attribute name passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.attributeNameCheck + (_isBasicCustomElement(lcTag) && + ((CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && + regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag)) || + (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && + CUSTOM_ELEMENT_HANDLING.tagNameCheck(lcTag))) && + ((CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof RegExp && + regExpTest(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName)) || + (CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof Function && + CUSTOM_ELEMENT_HANDLING.attributeNameCheck(lcName)))) || + // Alternative, second condition checks if it's an `is`-attribute, AND + // the value passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck + (lcName === 'is' && + CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements && + ((CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && + regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, value)) || + (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && + CUSTOM_ELEMENT_HANDLING.tagNameCheck(value)))) + ) { + // If user has supplied a regexp or function in CUSTOM_ELEMENT_HANDLING.tagNameCheck, we need to also allow derived custom elements using the same tagName test. + // Additionally, we need to allow attributes passing the CUSTOM_ELEMENT_HANDLING.attributeNameCheck user has configured, as custom elements can define these at their own discretion. + } else { + return false; + } + /* Check value is safe. First, is attr inert? If so, is safe */ + } else if (URI_SAFE_ATTRIBUTES[lcName]) { + // This attribute is safe + /* Check no script, data or unknown possibly unsafe URI + unless we know URI values are safe for that attribute */ + } else if ( + regExpTest(IS_ALLOWED_URI, stringReplace(value, ATTR_WHITESPACE, '')) + ) { + // This attribute is safe + /* Keep image data URIs alive if src/xlink:href is allowed */ + /* Further prevent gadget XSS for dynamically built script tags */ + } else if ( + (lcName === 'src' || lcName === 'xlink:href' || lcName === 'href') && + lcTag !== 'script' && + stringIndexOf(value, 'data:') === 0 && + DATA_URI_TAGS[lcTag] + ) { + // This attribute is safe + /* Allow unknown protocols: This provides support for links that + are handled by protocol handlers which may be unknown ahead of + time, e.g. fb:, spotify: */ + } else if ( + ALLOW_UNKNOWN_PROTOCOLS && + !regExpTest(IS_SCRIPT_OR_DATA, stringReplace(value, ATTR_WHITESPACE, '')) + ) { + // This attribute is safe + /* Check for binary attributes */ + } else if (value) { + return false; + } else { + // Binary attributes are safe at this point + /* Anything else, presume unsafe, do not add it back */ + } + + return true; + }; + + /** + * _isBasicCustomElement + * checks if at least one dash is included in tagName, and it's not the first char + * for more sophisticated checking see https://github.com/sindresorhus/validate-element-name + * + * @param {string} tagName name of the tag of the node to sanitize + * @returns {boolean} Returns true if the tag name meets the basic criteria for a custom element, otherwise false. + */ + const _isBasicCustomElement = function (tagName) { + return tagName.indexOf('-') > 0; + }; + + /** + * _sanitizeAttributes + * + * @protect attributes + * @protect nodeName + * @protect removeAttribute + * @protect setAttribute + * + * @param {Node} currentNode to sanitize + */ + const _sanitizeAttributes = function (currentNode) { + /* Execute a hook if present */ + _executeHook('beforeSanitizeAttributes', currentNode, null); + + const { attributes } = currentNode; + + /* Check if we have attributes; if not we might have a text node */ + if (!attributes) { + return; + } + + const hookEvent = { + attrName: '', + attrValue: '', + keepAttr: true, + allowedAttributes: ALLOWED_ATTR, + }; + let l = attributes.length; + + /* Go backwards over all attributes; safely remove bad ones */ + while (l--) { + const attr = attributes[l]; + const { name, namespaceURI, value: attrValue } = attr; + const lcName = transformCaseFunc(name); + + let value = name === 'value' ? attrValue : stringTrim(attrValue); + + /* Execute a hook if present */ + hookEvent.attrName = lcName; + hookEvent.attrValue = value; + hookEvent.keepAttr = true; + hookEvent.forceKeepAttr = undefined; // Allows developers to see this is a property they can set + _executeHook('uponSanitizeAttribute', currentNode, hookEvent); + value = hookEvent.attrValue; + /* Did the hooks approve of the attribute? */ + if (hookEvent.forceKeepAttr) { + continue; + } + + /* Remove attribute */ + _removeAttribute(name, currentNode); + + /* Did the hooks approve of the attribute? */ + if (!hookEvent.keepAttr) { + continue; + } + + /* Work around a security issue in jQuery 3.0 */ + if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(/\/>/i, value)) { + _removeAttribute(name, currentNode); + continue; + } + + /* Sanitize attribute content to be template-safe */ + if (SAFE_FOR_TEMPLATES) { + arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], (expr) => { + value = stringReplace(value, expr, ' '); + }); + } + + /* Is `value` valid for this attribute? */ + const lcTag = transformCaseFunc(currentNode.nodeName); + if (!_isValidAttribute(lcTag, lcName, value)) { + continue; + } + + /* Full DOM Clobbering protection via namespace isolation, + * Prefix id and name attributes with `user-content-` + */ + if (SANITIZE_NAMED_PROPS && (lcName === 'id' || lcName === 'name')) { + // Remove the attribute with this value + _removeAttribute(name, currentNode); + + // Prefix the value and later re-create the attribute with the sanitized value + value = SANITIZE_NAMED_PROPS_PREFIX + value; + } + + /* Handle attributes that require Trusted Types */ + if ( + trustedTypesPolicy && + typeof trustedTypes === 'object' && + typeof trustedTypes.getAttributeType === 'function' + ) { + if (namespaceURI) { + /* Namespaces are not yet supported, see https://bugs.chromium.org/p/chromium/issues/detail?id=1305293 */ + } else { + switch (trustedTypes.getAttributeType(lcTag, lcName)) { + case 'TrustedHTML': { + value = trustedTypesPolicy.createHTML(value); + break; + } + + case 'TrustedScriptURL': { + value = trustedTypesPolicy.createScriptURL(value); + break; + } + + default: { + break; + } + } + } + } + + /* Handle invalid data-* attribute set by try-catching it */ + try { + if (namespaceURI) { + currentNode.setAttributeNS(namespaceURI, name, value); + } else { + /* Fallback to setAttribute() for browser-unrecognized namespaces e.g. "x-schema". */ + currentNode.setAttribute(name, value); + } + + arrayPop(DOMPurify.removed); + } catch (_) {} + } + + /* Execute a hook if present */ + _executeHook('afterSanitizeAttributes', currentNode, null); + }; + + /** + * _sanitizeShadowDOM + * + * @param {DocumentFragment} fragment to iterate over recursively + */ + const _sanitizeShadowDOM = function (fragment) { + let shadowNode = null; + const shadowIterator = _createNodeIterator(fragment); + + /* Execute a hook if present */ + _executeHook('beforeSanitizeShadowDOM', fragment, null); + + while ((shadowNode = shadowIterator.nextNode())) { + /* Execute a hook if present */ + _executeHook('uponSanitizeShadowNode', shadowNode, null); + + /* Sanitize tags and elements */ + if (_sanitizeElements(shadowNode)) { + continue; + } + + /* Deep shadow DOM detected */ + if (shadowNode.content instanceof DocumentFragment) { + _sanitizeShadowDOM(shadowNode.content); + } + + /* Check attributes, sanitize if necessary */ + _sanitizeAttributes(shadowNode); + } + + /* Execute a hook if present */ + _executeHook('afterSanitizeShadowDOM', fragment, null); + }; + + /** + * Sanitize + * Public method providing core sanitation functionality + * + * @param {String|Node} dirty string or DOM node + * @param {Object} cfg object + */ + // eslint-disable-next-line complexity + DOMPurify.sanitize = function (dirty, cfg = {}) { + let body = null; + let importedNode = null; + let currentNode = null; + let returnNode = null; + /* Make sure we have a string to sanitize. + DO NOT return early, as this will return the wrong type if + the user has requested a DOM object rather than a string */ + IS_EMPTY_INPUT = !dirty; + if (IS_EMPTY_INPUT) { + dirty = ''; + } + + /* Stringify, in case dirty is an object */ + if (typeof dirty !== 'string' && !_isNode(dirty)) { + if (typeof dirty.toString === 'function') { + dirty = dirty.toString(); + if (typeof dirty !== 'string') { + throw typeErrorCreate('dirty is not a string, aborting'); + } + } else { + throw typeErrorCreate('toString is not a function'); + } + } + + /* Return dirty HTML if DOMPurify cannot run */ + if (!DOMPurify.isSupported) { + return dirty; + } + + /* Assign config vars */ + if (!SET_CONFIG) { + _parseConfig(cfg); + } + + /* Clean up removed elements */ + DOMPurify.removed = []; + + /* Check if dirty is correctly typed for IN_PLACE */ + if (typeof dirty === 'string') { + IN_PLACE = false; + } + + if (IN_PLACE) { + /* Do some early pre-sanitization to avoid unsafe root nodes */ + if (dirty.nodeName) { + const tagName = transformCaseFunc(dirty.nodeName); + if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) { + throw typeErrorCreate( + 'root node is forbidden and cannot be sanitized in-place' + ); + } + } + } else if (dirty instanceof Node) { + /* If dirty is a DOM element, append to an empty document to avoid + elements being stripped by the parser */ + body = _initDocument(''); + importedNode = body.ownerDocument.importNode(dirty, true); + if (importedNode.nodeType === 1 && importedNode.nodeName === 'BODY') { + /* Node is already a body, use as is */ + body = importedNode; + } else if (importedNode.nodeName === 'HTML') { + body = importedNode; + } else { + // eslint-disable-next-line unicorn/prefer-dom-node-append + body.appendChild(importedNode); + } + } else { + /* Exit directly if we have nothing to do */ + if ( + !RETURN_DOM && + !SAFE_FOR_TEMPLATES && + !WHOLE_DOCUMENT && + // eslint-disable-next-line unicorn/prefer-includes + dirty.indexOf('<') === -1 + ) { + return trustedTypesPolicy && RETURN_TRUSTED_TYPE + ? trustedTypesPolicy.createHTML(dirty) + : dirty; + } + + /* Initialize the document to work on */ + body = _initDocument(dirty); + + /* Check we have a DOM node from the data */ + if (!body) { + return RETURN_DOM ? null : RETURN_TRUSTED_TYPE ? emptyHTML : ''; + } + } + + /* Remove first element node (ours) if FORCE_BODY is set */ + if (body && FORCE_BODY) { + _forceRemove(body.firstChild); + } + + /* Get node iterator */ + const nodeIterator = _createNodeIterator(IN_PLACE ? dirty : body); + + /* Now start iterating over the created document */ + while ((currentNode = nodeIterator.nextNode())) { + /* Sanitize tags and elements */ + if (_sanitizeElements(currentNode)) { + continue; + } + + /* Shadow DOM detected, sanitize it */ + if (currentNode.content instanceof DocumentFragment) { + _sanitizeShadowDOM(currentNode.content); + } + + /* Check attributes, sanitize if necessary */ + _sanitizeAttributes(currentNode); + } + + /* If we sanitized `dirty` in-place, return it. */ + if (IN_PLACE) { + return dirty; + } + + /* Return sanitized string or DOM */ + if (RETURN_DOM) { + if (RETURN_DOM_FRAGMENT) { + returnNode = createDocumentFragment.call(body.ownerDocument); + + while (body.firstChild) { + // eslint-disable-next-line unicorn/prefer-dom-node-append + returnNode.appendChild(body.firstChild); + } + } else { + returnNode = body; + } + + if (ALLOWED_ATTR.shadowroot || ALLOWED_ATTR.shadowrootmode) { + /* + AdoptNode() is not used because internal state is not reset + (e.g. the past names map of a HTMLFormElement), this is safe + in theory but we would rather not risk another attack vector. + The state that is cloned by importNode() is explicitly defined + by the specs. + */ + returnNode = importNode.call(originalDocument, returnNode, true); + } + + return returnNode; + } + + let serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML; + + /* Serialize doctype if allowed */ + if ( + WHOLE_DOCUMENT && + ALLOWED_TAGS['!doctype'] && + body.ownerDocument && + body.ownerDocument.doctype && + body.ownerDocument.doctype.name && + regExpTest(EXPRESSIONS.DOCTYPE_NAME, body.ownerDocument.doctype.name) + ) { + serializedHTML = + '\n' + serializedHTML; + } + + /* Sanitize final string template-safe */ + if (SAFE_FOR_TEMPLATES) { + arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], (expr) => { + serializedHTML = stringReplace(serializedHTML, expr, ' '); + }); + } + + return trustedTypesPolicy && RETURN_TRUSTED_TYPE + ? trustedTypesPolicy.createHTML(serializedHTML) + : serializedHTML; + }; + + /** + * Public method to set the configuration once + * setConfig + * + * @param {Object} cfg configuration object + */ + DOMPurify.setConfig = function (cfg = {}) { + _parseConfig(cfg); + SET_CONFIG = true; + }; + + /** + * Public method to remove the configuration + * clearConfig + * + */ + DOMPurify.clearConfig = function () { + CONFIG = null; + SET_CONFIG = false; + }; + + /** + * Public method to check if an attribute value is valid. + * Uses last set config, if any. Otherwise, uses config defaults. + * isValidAttribute + * + * @param {String} tag Tag name of containing element. + * @param {String} attr Attribute name. + * @param {String} value Attribute value. + * @return {Boolean} Returns true if `value` is valid. Otherwise, returns false. + */ + DOMPurify.isValidAttribute = function (tag, attr, value) { + /* Initialize shared config vars if necessary. */ + if (!CONFIG) { + _parseConfig({}); + } + + const lcTag = transformCaseFunc(tag); + const lcName = transformCaseFunc(attr); + return _isValidAttribute(lcTag, lcName, value); + }; + + /** + * AddHook + * Public method to add DOMPurify hooks + * + * @param {String} entryPoint entry point for the hook to add + * @param {Function} hookFunction function to execute + */ + DOMPurify.addHook = function (entryPoint, hookFunction) { + if (typeof hookFunction !== 'function') { + return; + } + + hooks[entryPoint] = hooks[entryPoint] || []; + arrayPush(hooks[entryPoint], hookFunction); + }; + + /** + * RemoveHook + * Public method to remove a DOMPurify hook at a given entryPoint + * (pops it from the stack of hooks if more are present) + * + * @param {String} entryPoint entry point for the hook to remove + * @return {Function} removed(popped) hook + */ + DOMPurify.removeHook = function (entryPoint) { + if (hooks[entryPoint]) { + return arrayPop(hooks[entryPoint]); + } + }; + + /** + * RemoveHooks + * Public method to remove all DOMPurify hooks at a given entryPoint + * + * @param {String} entryPoint entry point for the hooks to remove + */ + DOMPurify.removeHooks = function (entryPoint) { + if (hooks[entryPoint]) { + hooks[entryPoint] = []; + } + }; + + /** + * RemoveAllHooks + * Public method to remove all DOMPurify hooks + */ + DOMPurify.removeAllHooks = function () { + hooks = {}; + }; + + return DOMPurify; +} + +export default createDOMPurify(); diff --git a/src/ui/static/js/utils/purify/src/regexp.js b/src/ui/static/js/utils/purify/src/regexp.js new file mode 100644 index 000000000..3c9f75fef --- /dev/null +++ b/src/ui/static/js/utils/purify/src/regexp.js @@ -0,0 +1,16 @@ +import { seal } from './utils.js'; + +// eslint-disable-next-line unicorn/better-regex +export const MUSTACHE_EXPR = seal(/\{\{[\w\W]*|[\w\W]*\}\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode +export const ERB_EXPR = seal(/<%[\w\W]*|[\w\W]*%>/gm); +export const TMPLIT_EXPR = seal(/\${[\w\W]*}/gm); +export const DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]/); // eslint-disable-line no-useless-escape +export const ARIA_ATTR = seal(/^aria-[\-\w]+$/); // eslint-disable-line no-useless-escape +export const IS_ALLOWED_URI = seal( + /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i // eslint-disable-line no-useless-escape +); +export const IS_SCRIPT_OR_DATA = seal(/^(?:\w+script|data):/i); +export const ATTR_WHITESPACE = seal( + /[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g // eslint-disable-line no-control-regex +); +export const DOCTYPE_NAME = seal(/^html$/i); diff --git a/src/ui/static/js/utils/purify/src/tags.js b/src/ui/static/js/utils/purify/src/tags.js new file mode 100644 index 000000000..853c7308a --- /dev/null +++ b/src/ui/static/js/utils/purify/src/tags.js @@ -0,0 +1,280 @@ +import { freeze } from './utils.js'; + +export const html = freeze([ + 'a', + 'abbr', + 'acronym', + 'address', + 'area', + 'article', + 'aside', + 'audio', + 'b', + 'bdi', + 'bdo', + 'big', + 'blink', + 'blockquote', + 'body', + 'br', + 'button', + 'canvas', + 'caption', + 'center', + 'cite', + 'code', + 'col', + 'colgroup', + 'content', + 'data', + 'datalist', + 'dd', + 'decorator', + 'del', + 'details', + 'dfn', + 'dialog', + 'dir', + 'div', + 'dl', + 'dt', + 'element', + 'em', + 'fieldset', + 'figcaption', + 'figure', + 'font', + 'footer', + 'form', + 'h1', + 'h2', + 'h3', + 'h4', + 'h5', + 'h6', + 'head', + 'header', + 'hgroup', + 'hr', + 'html', + 'i', + 'img', + 'input', + 'ins', + 'kbd', + 'label', + 'legend', + 'li', + 'main', + 'map', + 'mark', + 'marquee', + 'menu', + 'menuitem', + 'meter', + 'nav', + 'nobr', + 'ol', + 'optgroup', + 'option', + 'output', + 'p', + 'picture', + 'pre', + 'progress', + 'q', + 'rp', + 'rt', + 'ruby', + 's', + 'samp', + 'section', + 'select', + 'shadow', + 'small', + 'source', + 'spacer', + 'span', + 'strike', + 'strong', + 'style', + 'sub', + 'summary', + 'sup', + 'table', + 'tbody', + 'td', + 'template', + 'textarea', + 'tfoot', + 'th', + 'thead', + 'time', + 'tr', + 'track', + 'tt', + 'u', + 'ul', + 'var', + 'video', + 'wbr', +]); + +// SVG +export const svg = freeze([ + 'svg', + 'a', + 'altglyph', + 'altglyphdef', + 'altglyphitem', + 'animatecolor', + 'animatemotion', + 'animatetransform', + 'circle', + 'clippath', + 'defs', + 'desc', + 'ellipse', + 'filter', + 'font', + 'g', + 'glyph', + 'glyphref', + 'hkern', + 'image', + 'line', + 'lineargradient', + 'marker', + 'mask', + 'metadata', + 'mpath', + 'path', + 'pattern', + 'polygon', + 'polyline', + 'radialgradient', + 'rect', + 'stop', + 'style', + 'switch', + 'symbol', + 'text', + 'textpath', + 'title', + 'tref', + 'tspan', + 'view', + 'vkern', +]); + +export const svgFilters = freeze([ + 'feBlend', + 'feColorMatrix', + 'feComponentTransfer', + 'feComposite', + 'feConvolveMatrix', + 'feDiffuseLighting', + 'feDisplacementMap', + 'feDistantLight', + 'feDropShadow', + 'feFlood', + 'feFuncA', + 'feFuncB', + 'feFuncG', + 'feFuncR', + 'feGaussianBlur', + 'feImage', + 'feMerge', + 'feMergeNode', + 'feMorphology', + 'feOffset', + 'fePointLight', + 'feSpecularLighting', + 'feSpotLight', + 'feTile', + 'feTurbulence', +]); + +// List of SVG elements that are disallowed by default. +// We still need to know them so that we can do namespace +// checks properly in case one wants to add them to +// allow-list. +export const svgDisallowed = freeze([ + 'animate', + 'color-profile', + 'cursor', + 'discard', + 'font-face', + 'font-face-format', + 'font-face-name', + 'font-face-src', + 'font-face-uri', + 'foreignobject', + 'hatch', + 'hatchpath', + 'mesh', + 'meshgradient', + 'meshpatch', + 'meshrow', + 'missing-glyph', + 'script', + 'set', + 'solidcolor', + 'unknown', + 'use', +]); + +export const mathMl = freeze([ + 'math', + 'menclose', + 'merror', + 'mfenced', + 'mfrac', + 'mglyph', + 'mi', + 'mlabeledtr', + 'mmultiscripts', + 'mn', + 'mo', + 'mover', + 'mpadded', + 'mphantom', + 'mroot', + 'mrow', + 'ms', + 'mspace', + 'msqrt', + 'mstyle', + 'msub', + 'msup', + 'msubsup', + 'mtable', + 'mtd', + 'mtext', + 'mtr', + 'munder', + 'munderover', + 'mprescripts', +]); + +// Similarly to SVG, we want to know all MathML elements, +// even those that we disallow by default. +export const mathMlDisallowed = freeze([ + 'maction', + 'maligngroup', + 'malignmark', + 'mlongdiv', + 'mscarries', + 'mscarry', + 'msgroup', + 'mstack', + 'msline', + 'msrow', + 'semantics', + 'annotation', + 'annotation-xml', + 'mprescripts', + 'none', +]); + +export const text = freeze(['#text']); diff --git a/src/ui/static/js/utils/purify/src/utils.js b/src/ui/static/js/utils/purify/src/utils.js new file mode 100644 index 000000000..a658514f8 --- /dev/null +++ b/src/ui/static/js/utils/purify/src/utils.js @@ -0,0 +1,193 @@ +const { + entries, + setPrototypeOf, + isFrozen, + getPrototypeOf, + getOwnPropertyDescriptor, +} = Object; + +let { freeze, seal, create } = Object; // eslint-disable-line import/no-mutable-exports +let { apply, construct } = typeof Reflect !== 'undefined' && Reflect; + +if (!freeze) { + freeze = function (x) { + return x; + }; +} + +if (!seal) { + seal = function (x) { + return x; + }; +} + +if (!apply) { + apply = function (fun, thisValue, args) { + return fun.apply(thisValue, args); + }; +} + +if (!construct) { + construct = function (Func, args) { + return new Func(...args); + }; +} + +const arrayForEach = unapply(Array.prototype.forEach); +const arrayIndexOf = unapply(Array.prototype.indexOf); +const arrayPop = unapply(Array.prototype.pop); +const arrayPush = unapply(Array.prototype.push); +const arraySlice = unapply(Array.prototype.slice); + +const stringToLowerCase = unapply(String.prototype.toLowerCase); +const stringToString = unapply(String.prototype.toString); +const stringMatch = unapply(String.prototype.match); +const stringReplace = unapply(String.prototype.replace); +const stringIndexOf = unapply(String.prototype.indexOf); +const stringTrim = unapply(String.prototype.trim); + +const regExpTest = unapply(RegExp.prototype.test); + +const typeErrorCreate = unconstruct(TypeError); + +/** + * Creates a new function that calls the given function with a specified thisArg and arguments. + * + * @param {Function} func - The function to be wrapped and called. + * @returns {Function} A new function that calls the given function with a specified thisArg and arguments. + */ +function unapply(func) { + return (thisArg, ...args) => apply(func, thisArg, args); +} + +/** + * Creates a new function that constructs an instance of the given constructor function with the provided arguments. + * + * @param {Function} func - The constructor function to be wrapped and called. + * @returns {Function} A new function that constructs an instance of the given constructor function with the provided arguments. + */ +function unconstruct(func) { + return (...args) => construct(func, args); +} + +/** + * Add properties to a lookup table + * + * @param {Object} set - The set to which elements will be added. + * @param {Array} array - The array containing elements to be added to the set. + * @param {Function} transformCaseFunc - An optional function to transform the case of each element before adding to the set. + * @returns {Object} The modified set with added elements. + */ +function addToSet(set, array, transformCaseFunc = stringToLowerCase) { + if (setPrototypeOf) { + // Make 'in' and truthy checks like Boolean(set.constructor) + // independent of any properties defined on Object.prototype. + // Prevent prototype setters from intercepting set as a this value. + setPrototypeOf(set, null); + } + + let l = array.length; + while (l--) { + let element = array[l]; + if (typeof element === 'string') { + const lcElement = transformCaseFunc(element); + if (lcElement !== element) { + // Config presets (e.g. tags.js, attrs.js) are immutable. + if (!isFrozen(array)) { + array[l] = lcElement; + } + + element = lcElement; + } + } + + set[element] = true; + } + + return set; +} + +/** + * Shallow clone an object + * + * @param {Object} object - The object to be cloned. + * @returns {Object} A new object that copies the original. + */ +export function clone(object) { + const newObject = create(null); + + for (const [property, value] of entries(object)) { + if (getOwnPropertyDescriptor(object, property) !== undefined) { + newObject[property] = value; + } + } + + return newObject; +} + +/** + * This method automatically checks if the prop is function or getter and behaves accordingly. + * + * @param {Object} object - The object to look up the getter function in its prototype chain. + * @param {String} prop - The property name for which to find the getter function. + * @returns {Function} The getter function found in the prototype chain or a fallback function. + */ +function lookupGetter(object, prop) { + while (object !== null) { + const desc = getOwnPropertyDescriptor(object, prop); + + if (desc) { + if (desc.get) { + return unapply(desc.get); + } + + if (typeof desc.value === 'function') { + return unapply(desc.value); + } + } + + object = getPrototypeOf(object); + } + + function fallbackValue(element) { + console.warn('fallback value for', element); + return null; + } + + return fallbackValue; +} + +export { + // Array + arrayForEach, + arrayIndexOf, + arrayPop, + arrayPush, + arraySlice, + // Object + entries, + freeze, + getPrototypeOf, + getOwnPropertyDescriptor, + isFrozen, + setPrototypeOf, + seal, + create, + // RegExp + regExpTest, + // String + stringIndexOf, + stringMatch, + stringReplace, + stringToLowerCase, + stringToString, + stringTrim, + // Errors + typeErrorCreate, + // Other + lookupGetter, + addToSet, + // Reflect + unapply, + unconstruct, +}; diff --git a/src/ui/static/js/utils/settings.js b/src/ui/static/js/utils/settings.js index de107d222..b7d8c2c63 100644 --- a/src/ui/static/js/utils/settings.js +++ b/src/ui/static/js/utils/settings.js @@ -1,239 +1,239 @@ -class Popover { - constructor() { - this.init(); - } - - init() { - window.addEventListener("pointerover", (e) => { - //POPOVER LOGIC - try { - if (e.target.closest("svg").hasAttribute(`data-popover-btn`)) { - this.showPopover(e.target); - } - } catch (err) {} - }); - - window.addEventListener("pointerout", (e) => { - //POPOVER LOGIC - try { - if (e.target.closest("svg").hasAttribute(`data-popover-btn`)) { - this.hidePopover(e.target); - } - } catch (err) {} - }); - } - - showPopover(el) { - const btn = el.closest("svg"); - //toggle curr popover - const popover = btn.parentElement.querySelector(`[data-popover-content]`); - popover.classList.remove("hidden"); - } - - hidePopover(el) { - const btn = el.closest("svg"); - //toggle curr popover - const popover = btn.parentElement.querySelector(`[data-popover-content]`); - popover.classList.add("hidden"); - } -} - -class Tabs { - constructor() { - this.init(); - } - - init() { - window.addEventListener("click", (e) => { - try { - if ( - e.target.closest("button").hasAttribute("data-tab-handler") || - e.target.closest("button").hasAttribute("data-tab-handler-mobile") - ) { - //get needed data - const tab = e.target.closest("button"); - const tabAtt = - tab.getAttribute("data-tab-handler") || - tab.getAttribute("data-tab-handler-mobile"); - const container = tab.closest("div[data-service-content]"); - // change style - this.resetTabsStyle(container); - this.highlightClicked(container, tabAtt); - //show content - this.hideAllSettings(container); - this.showSettingClicked(container, tabAtt); - //close dropdown and change btn textcontent on mobile - this.setDropBtnText(container, tabAtt); - this.closeDropdown(container); - } - } catch (err) {} - - try { - if (e.target.closest("button").hasAttribute("data-tab-dropdown-btn")) { - const dropBtn = e.target.closest("button"); - const container = dropBtn.closest("div[data-service-content]"); - this.toggleDropdown(container); - } - } catch (err) {} - }); - } - - resetTabsStyle(container) { - //reset desktop style - const tabsDesktop = container.querySelectorAll("button[data-tab-handler]"); - tabsDesktop.forEach((tab) => { - tab.classList.remove("active"); - }); - //reset mobile style - const tabsMobile = container.querySelectorAll( - "button[data-tab-handler-mobile]" - ); - tabsMobile.forEach((tab) => { - tab.classList.remove("active"); - }); - } - - highlightClicked(container, tabAtt) { - //desktop case - const tabDesktop = container.querySelector( - `button[data-tab-handler='${tabAtt}']` - ); - tabDesktop.classList.add("active"); - - //mobile case - const tabMobile = container.querySelector( - `button[data-tab-handler-mobile='${tabAtt}']` - ); - tabMobile.classList.add("active"); - } - - hideAllSettings(container) { - const plugins = container.querySelectorAll("[data-plugin-item]"); - plugins.forEach((plugin) => { - plugin.classList.add("hidden"); - }); - } - - showSettingClicked(container, tabAtt) { - const plugin = container.querySelector(`[data-plugin-item='${tabAtt}']`); - plugin.classList.remove("hidden"); - } - - setDropBtnText(container, tabAtt) { - const dropBtn = container.querySelector("[data-tab-dropdown-btn]"); - dropBtn.querySelector("span").textContent = tabAtt; - } - - closeDropdown(container) { - const dropdown = container.querySelector("[data-tab-dropdown]"); - dropdown.classList.add("hidden"); - dropdown.classList.remove("flex"); - } - - toggleDropdown(container) { - const dropdown = container.querySelector("[data-tab-dropdown]"); - dropdown.classList.toggle("hidden"); - dropdown.classList.toggle("flex"); - } -} - -class FormatValue { - constructor() { - this.inputs = document.querySelectorAll("input"); - this.init(); - } - - init() { - this.inputs.forEach((inp) => { - try { - inp.setAttribute("value", inp.getAttribute("value").trim()); - inp.value = inp.value.trim(); - } catch (err) {} - }); - } -} - -class FilterSettings { - constructor(inputID, container) { - this.input = document.querySelector(`input#${inputID}`); - //DESKTOP - this.container = document.querySelector(container); - this.deskTabs = this.container.querySelectorAll(`[data-tab-handler]`); - this.init(); - } - - init() { - this.input.addEventListener("input", () => { - this.resetFilter(); - //get inp format - const inpValue = this.input.value.trim().toLowerCase(); - //loop all tabs - this.deskTabs.forEach((tab) => { - //get settings of tabs except multiples - const settings = this.getSettingsFromTab(tab); - - //compare total count to currCount to determine - //if tabs need to be hidden - const settingCount = settings.length; - let hiddenCount = 0; - settings.forEach((setting) => { - try { - const title = setting - .querySelector("h5") - .textContent.trim() - .toLowerCase(); - if (!title.includes(inpValue)) { - setting.classList.add("hidden"); - hiddenCount++; - } - } catch (err) {} - }); - //case no setting match, hidden tab and content - if (settingCount === hiddenCount) { - const tabName = tab.getAttribute(`data-tab-handler`); - //hide mobile and desk tabs - tab.classList.add("hidden"); - this.container - .querySelector(`[data-tab-handler-mobile="${tabName}"]`) - .classList.add("hidden"); - this.container - .querySelector(`[data-plugin-item=${tabName}]`) - .querySelector("[data-setting-header]") - .classList.add("hidden"); - } - }); - }); - } - - resetFilter() { - this.deskTabs.forEach((tab) => { - const tabName = tab.getAttribute(`data-tab-handler`); - //hide mobile and desk tabs - tab.classList.remove("hidden"); - this.container - .querySelector(`[data-tab-handler-mobile="${tabName}"]`) - .classList.remove("hidden"); - this.container - .querySelector(`[data-plugin-item=${tabName}]`) - .querySelector("[data-setting-header]") - .classList.remove("hidden"); - const settings = this.getSettingsFromTab(tab); - settings.forEach((setting) => { - setting.classList.remove("hidden"); - }); - }); - } - - getSettingsFromTab(tabEl) { - const tabName = tabEl.getAttribute(`data-tab-handler`); - const settingContainer = this.container - .querySelector(`[data-plugin-item="${tabName}"]`) - .querySelector(`[data-plugin-settings]`); - const settings = settingContainer.querySelectorAll( - "[data-setting-container]" - ); - return settings; - } -} - -export { Popover, Tabs, FormatValue, FilterSettings }; +class Popover { + constructor() { + this.init(); + } + + init() { + window.addEventListener("pointerover", (e) => { + //POPOVER LOGIC + try { + if (e.target.closest("svg").hasAttribute(`data-popover-btn`)) { + this.showPopover(e.target); + } + } catch (err) {} + }); + + window.addEventListener("pointerout", (e) => { + //POPOVER LOGIC + try { + if (e.target.closest("svg").hasAttribute(`data-popover-btn`)) { + this.hidePopover(e.target); + } + } catch (err) {} + }); + } + + showPopover(el) { + const btn = el.closest("svg"); + //toggle curr popover + const popover = btn.parentElement.querySelector(`[data-popover-content]`); + popover.classList.remove("hidden"); + } + + hidePopover(el) { + const btn = el.closest("svg"); + //toggle curr popover + const popover = btn.parentElement.querySelector(`[data-popover-content]`); + popover.classList.add("hidden"); + } +} + +class Tabs { + constructor() { + this.init(); + } + + init() { + window.addEventListener("click", (e) => { + try { + if ( + e.target.closest("button").hasAttribute("data-tab-handler") || + e.target.closest("button").hasAttribute("data-tab-handler-mobile") + ) { + //get needed data + const tab = e.target.closest("button"); + const tabAtt = + tab.getAttribute("data-tab-handler") || + tab.getAttribute("data-tab-handler-mobile"); + const container = tab.closest("div[data-service-content]"); + // change style + this.resetTabsStyle(container); + this.highlightClicked(container, tabAtt); + //show content + this.hideAllSettings(container); + this.showSettingClicked(container, tabAtt); + //close dropdown and change btn textcontent on mobile + this.setDropBtnText(container, tabAtt); + this.closeDropdown(container); + } + } catch (err) {} + + try { + if (e.target.closest("button").hasAttribute("data-tab-dropdown-btn")) { + const dropBtn = e.target.closest("button"); + const container = dropBtn.closest("div[data-service-content]"); + this.toggleDropdown(container); + } + } catch (err) {} + }); + } + + resetTabsStyle(container) { + //reset desktop style + const tabsDesktop = container.querySelectorAll("button[data-tab-handler]"); + tabsDesktop.forEach((tab) => { + tab.classList.remove("active"); + }); + //reset mobile style + const tabsMobile = container.querySelectorAll( + "button[data-tab-handler-mobile]", + ); + tabsMobile.forEach((tab) => { + tab.classList.remove("active"); + }); + } + + highlightClicked(container, tabAtt) { + //desktop case + const tabDesktop = container.querySelector( + `button[data-tab-handler='${tabAtt}']`, + ); + tabDesktop.classList.add("active"); + + //mobile case + const tabMobile = container.querySelector( + `button[data-tab-handler-mobile='${tabAtt}']`, + ); + tabMobile.classList.add("active"); + } + + hideAllSettings(container) { + const plugins = container.querySelectorAll("[data-plugin-item]"); + plugins.forEach((plugin) => { + plugin.classList.add("hidden"); + }); + } + + showSettingClicked(container, tabAtt) { + const plugin = container.querySelector(`[data-plugin-item='${tabAtt}']`); + plugin.classList.remove("hidden"); + } + + setDropBtnText(container, tabAtt) { + const dropBtn = container.querySelector("[data-tab-dropdown-btn]"); + dropBtn.querySelector("span").textContent = tabAtt; + } + + closeDropdown(container) { + const dropdown = container.querySelector("[data-tab-dropdown]"); + dropdown.classList.add("hidden"); + dropdown.classList.remove("flex"); + } + + toggleDropdown(container) { + const dropdown = container.querySelector("[data-tab-dropdown]"); + dropdown.classList.toggle("hidden"); + dropdown.classList.toggle("flex"); + } +} + +class FormatValue { + constructor() { + this.inputs = document.querySelectorAll("input"); + this.init(); + } + + init() { + this.inputs.forEach((inp) => { + try { + inp.setAttribute("value", inp.getAttribute("value").trim()); + inp.value = inp.value.trim(); + } catch (err) {} + }); + } +} + +class FilterSettings { + constructor(inputID, container) { + this.input = document.querySelector(`input#${inputID}`); + //DESKTOP + this.container = document.querySelector(container); + this.deskTabs = this.container.querySelectorAll(`[data-tab-handler]`); + this.init(); + } + + init() { + this.input.addEventListener("input", () => { + this.resetFilter(); + //get inp format + const inpValue = this.input.value.trim().toLowerCase(); + //loop all tabs + this.deskTabs.forEach((tab) => { + //get settings of tabs except multiples + const settings = this.getSettingsFromTab(tab); + + //compare total count to currCount to determine + //if tabs need to be hidden + const settingCount = settings.length; + let hiddenCount = 0; + settings.forEach((setting) => { + try { + const title = setting + .querySelector("h5") + .textContent.trim() + .toLowerCase(); + if (!title.includes(inpValue)) { + setting.classList.add("hidden"); + hiddenCount++; + } + } catch (err) {} + }); + //case no setting match, hidden tab and content + if (settingCount === hiddenCount) { + const tabName = tab.getAttribute(`data-tab-handler`); + //hide mobile and desk tabs + tab.classList.add("hidden"); + this.container + .querySelector(`[data-tab-handler-mobile="${tabName}"]`) + .classList.add("hidden"); + this.container + .querySelector(`[data-plugin-item=${tabName}]`) + .querySelector("[data-setting-header]") + .classList.add("hidden"); + } + }); + }); + } + + resetFilter() { + this.deskTabs.forEach((tab) => { + const tabName = tab.getAttribute(`data-tab-handler`); + //hide mobile and desk tabs + tab.classList.remove("hidden"); + this.container + .querySelector(`[data-tab-handler-mobile="${tabName}"]`) + .classList.remove("hidden"); + this.container + .querySelector(`[data-plugin-item=${tabName}]`) + .querySelector("[data-setting-header]") + .classList.remove("hidden"); + const settings = this.getSettingsFromTab(tab); + settings.forEach((setting) => { + setting.classList.remove("hidden"); + }); + }); + } + + getSettingsFromTab(tabEl) { + const tabName = tabEl.getAttribute(`data-tab-handler`); + const settingContainer = this.container + .querySelector(`[data-plugin-item="${tabName}"]`) + .querySelector(`[data-plugin-settings]`); + const settings = settingContainer.querySelectorAll( + "[data-setting-container]", + ); + return settings; + } +} + +export { Popover, Tabs, FormatValue, FilterSettings }; diff --git a/src/ui/static/webfonts/bootstrap-icons.css b/src/ui/static/webfonts/bootstrap-icons.css index facb2077f..7a092af21 100644 --- a/src/ui/static/webfonts/bootstrap-icons.css +++ b/src/ui/static/webfonts/bootstrap-icons.css @@ -1,6 +1,7 @@ @font-face { font-family: "bootstrap-icons"; - src: url("./bootstrap-icons.woff2?524846017b983fc8ded9325d94ed40f3") + src: + url("./bootstrap-icons.woff2?524846017b983fc8ded9325d94ed40f3") format("woff2"), url("./bootstrap-icons.woff?524846017b983fc8ded9325d94ed40f3") format("woff"); diff --git a/src/ui/templates/head.html b/src/ui/templates/head.html index c9a4ed862..90f58f9e4 100644 --- a/src/ui/templates/head.html +++ b/src/ui/templates/head.html @@ -18,7 +18,8 @@ - + + {% if current_endpoint == "global_config" %} @@ -33,7 +34,7 @@ {% elif current_endpoint == "logs" %} - +